This page describes how to construct a RPC Request object. The page starts from the protocol grammar and then creates sequence diagrams.
The sequence diagrams are meant to be converted to code.
The ABNF Grammar.
ProcIDSwitch = %xFF %xFF
ProcName = US_VARCHAR
NameLenProcID = ProcName
/
(ProcIDSwitch ProcID)
fWithRecomp = BIT
fNoMetaData = BIT
fReuseMetaData = BIT
OptionFlags = fWithRecomp
fNoMetaData
fReuseMetaData
13FRESERVEDBIT
fByRefValue = BIT
fDefaultValue = BIT
fEncrypted = BIT
StatusFlags = fByRefValue
fDefaultValue
1FRESERVEDBIT
fEncrypted
4FRESERVEDBIT
ParamMetaData = B_VARCHAR
StatusFlags
(TYPE_INFO / TVP_TYPE_INFO) ; (TVP_TYPE_INFO introduced in TDS 7.3)
ParamLenData = TYPE_VARBYTE
EncryptionAlgo = BYTE ; (introduced in TDS 7.4)
AlgoName = B_VARCHAR ; (introduced in TDS 7.4)
EncryptionType = BYTE ; (introduced in TDS 7.4)
NormVersion = BYTE ; (introduced in TDS 7.4)
DatabaseId = ULONG ; (introduced in TDS 7.4)
CekId = ULONG ; (introduced in TDS 7.4)
CekVersion = ULONG ; (introduced in TDS 7.4)
CekMDVersion = ULONGLONG ; (introduced in TDS 7.4)
ParamCipherInfo = TYPE_INFO
EncryptionAlgo
[AlgoName]
EncryptionType
DatabaseId
CekId
CekVersion
CekMDVersion
NormVersion
ParameterData = ParamMetaData
ParamLenData
[ParamCipherInfo]
EnclavePackage = L_VARBYTE ; (introduced in TDS 7.4)
BatchFlag = %x80 / %xFF ; (changed to %xFF in TDS 7.2)
NoExecFlag = %xFE ; (introduced in TDS 7.2)
RPCReqBatch = NameLenProcID
OptionFlags
*EnclavePackage
*ParameterData
RPCRequest = ALL_HEADERS
RPCReqBatch
*((BatchFlag / NoExecFlag) RPCReqBatch)
[BatchFlag / NoExecFlag]
TYPE_VARBYTE = GEN_NULL / CHARBIN_NULL / PLP_BODY / ([TYPE_VARLEN] *BYTE)
RPCRequest = ALL_HEADERS
RPCReqBatch
*((BatchFlag / NoExecFlag) RPCReqBatch)
[BatchFlag / NoExecFlag]
sequenceDiagram
participant User
participant System
Note over User, System: RPCRequest begins
User->>System: ALL_HEADERS
User->>System: RPCReqBatch
loop Zero or more times
alt BatchFlag
User->>System: BatchFlag
else NoExecFlag
User->>System: NoExecFlag
end
User->>System: RPCReqBatch
end
alt Optional BatchFlag or NoExecFlag
User->>System: BatchFlag / NoExecFlag
end
Note over User, System: RPCRequest ends
RPCReqBatch = NameLenProcID
OptionFlags
*EnclavePackage
*ParameterData
sequenceDiagram
participant User
participant System
Note over User, System: RPCRequest begins
User->>System: ALL_HEADERS
User->>System: RPCReqBatch
loop Zero or more times
alt BatchFlag
User->>System: BatchFlag
else NoExecFlag
User->>System: NoExecFlag
end
User->>System: RPCReqBatch
end
alt Optional BatchFlag or NoExecFlag
User->>System: BatchFlag / NoExecFlag
end
Note over User, System: RPCRequest ends
NameLenProcID = ProcName
/
(ProcIDSwitch ProcID)
sequenceDiagram
participant User
participant System
alt ProcName
User->>System: ProcName (US_VARCHAR)
else ProcIDSwitch
User->>System: ProcIDSwitch (%xFF %xFF)
User->>System: ProcID
end
fWithRecomp = BIT
fNoMetaData = BIT
fReuseMetaData = BIT
OptionFlags = fWithRecomp
fNoMetaData
fReuseMetaData
13FRESERVEDBIT
sequenceDiagram
participant User
participant System
User->>System: fWithRecomp (BIT)
User->>System: fNoMetaData (BIT)
User->>System: fReuseMetaData (BIT)
User->>System: 13FRESERVEDBIT
fByRefValue = BIT
fDefaultValue = BIT
fEncrypted = BIT
StatusFlags = fByRefValue
fDefaultValue
1FRESERVEDBIT
fEncrypted
4FRESERVEDBIT
sequenceDiagram
participant User
participant System
User->>System: fByRefValue (BIT)
User->>System: fDefaultValue (BIT)
User->>System: 1FRESERVEDBIT
User->>System: fEncrypted (BIT)
User->>System: 4FRESERVEDBIT
ParamMetaData = B_VARCHAR
StatusFlags
(TYPE_INFO / TVP_TYPE_INFO) ; (TVP_TYPE_INFO introduced in TDS 7.3)
ImplNote: ParamMetaData -> The name (B_VARCHAR) should have a @ prefixed to the parameter name, if it doesn’t already have one.
StatusFlags:
// Options is the status flag.
if (index < systemParamCount)
{
retval = systemParams[index];
options = systemParamOptions[index];
}
else
{
long data = userParamMap[index - systemParamCount];
int paramIndex = (int)(data & int.MaxValue);
options = (byte)((data >> 32) & 0xFF);
retval = userParams[paramIndex];
}
sequenceDiagram
participant User
participant System
User->>System: B_VARCHAR
User->>System: StatusFlags
alt TYPE_INFO
User->>System: TYPE_INFO
else TVP_TYPE_INFO
User->>System: TVP_TYPE_INFO
end
ParamCipherInfo = TYPE_INFO
EncryptionAlgo
[AlgoName]
EncryptionType
DatabaseId
CekId
CekVersion
CekMDVersion
NormVersion
sequenceDiagram
participant User
participant System
User->>System: TYPE_INFO
User->>System: EncryptionAlgo (BYTE)
opt AlgoName
User->>System: AlgoName (B_VARCHAR)
end
User->>System: EncryptionType (BYTE)
User->>System: DatabaseId (ULONG)
User->>System: CekId (ULONG)
User->>System: CekVersion (ULONG)
User->>System: CekMDVersion (ULONGLONG)
User->>System: NormVersion (BYTE)
ParameterData = ParamMetaData
ParamLenData
[ParamCipherInfo]
sequenceDiagram
participant User
participant System
User->>System: ParamMetaData
User->>System: ParamLenData (TYPE_VARBYTE)
opt ParamCipherInfo
User->>System: ParamCipherInfo
end
TYPE_VARLEN in the ParameterData signifies that we only send the Nullable types of any datatypes, while sending RPC request.