Похоже, ваше замешательство происходит из-за неправильного понимания, что такое varbinary
.varbinary
- это строка байтов, а не символов.Это даже не строка, это массив байтов.
varbinary
может быть представлен в виде строки шестнадцатеричных значений, а константы varbinary
в коде T-SQL представлены в виде шестнадцатеричных строк.Два шестнадцатеричных символа на байт.
Функция SUBSTRING
в T-SQL может работать со строками (varchar
) и байтами (varbinary
).
Синтаксис
SUBSTRING (выражение, начало, длина)
Значения для начала и длины должны быть указаны в количестве символов для ntext
, char
, или varchar
типы данных и байты для text
, image
, binary
или varbinary
типов данных.
Итак, следующие TКод триггера -SQL
declare @ctxt varbinary(128)
select @ctxt=context_info from master.dbo.sysprocesses where spid = @@spid
set @session=substring(@ctxt,1,4)
берет первые 4 байта ( не символы ) из массива байтов @ctxt
и присваивает их переменной @session
.Какой тип @session
?Скорее всего, это int
.
Запустите этот пример кода в SSMS, и вы увидите шестнадцатеричное представление некоторых целых чисел:
DECLARE @T TABLE (I int);
INSERT INTO @T VALUES
(0),
(1),
(3),
(19),
(255),
(256),
(512),
(768),
(4098),
(65535),
(65536),
(131072),
(1234567890),
(-1),
(-65535);
SELECT
I, CONVERT(varbinary(120), I) AS BinI
FROM @T;
Результат
+------------+------------+
| I | BinI |
+------------+------------+
| 0 | 0x00000000 |
| 1 | 0x00000001 |
| 3 | 0x00000003 |
| 19 | 0x00000013 |
| 255 | 0x000000FF |
| 256 | 0x00000100 |
| 512 | 0x00000200 |
| 768 | 0x00000300 |
| 4098 | 0x00001002 |
| 65535 | 0x0000FFFF |
| 65536 | 0x00010000 |
| 131072 | 0x00020000 |
| 1234567890 | 0x499602D2 |
| -1 | 0xFFFFFFFF |
| -65535 | 0xFFFF0001 |
+------------+------------+
Ваш код C # в вопросе не имеет особого смысла.Включение strInt + strUser
в CONVERT(varbinary(120), N'" + strContextValue + "')
не имеет смысла.
Код C # должен создавать двоичный массив.Код триггера T-SQL предполагает, что первые 4 байта этого массива равны @session
, следующие 4 байта - @contextid
. байтов, а не символов .
Итак, если вы хотите передать, скажем, 131072
десятичный как @session
, 1234567890
десятичный как @contextid
, плюс myself$
строкав качестве дополнительной информации вы должны запустить следующий код T-SQL:
declare @context_info varbinary(128); -- note 128 length here
set @context_info = 0x00020000;
-- note, there are no quotes around the constants, they are numbers, not strings
set @context_info = @context_info + 0x499602D2;
set @context_info = @context_info + CONVERT(varbinary(120), N'myself$');
-- note 120 length here, first 8 bytes are used by two integers
set context_info @context_info;
Запустите этот код в SSMS, но замените последнюю строку на SELECT @context_info;
, чтобы увидеть, что он делает.Вы получите следующий результат:
+------------------------------------------------+
| (No column name) |
+------------------------------------------------+
| 0x00020000499602D26D007900730065006C0066002400 |
+------------------------------------------------+
Вы можете увидеть двоичное представление двух целых чисел плюс двоичное представление текстовой строки Unicode.
В C # вы создаете этот код путем объединения шестнадцатеричного числапредставление целых чисел.Обратите внимание, что вы не должны заключать 0x00020000
и 0x499602D2
в кавычки или CONVERT(varbinary, ...)
.Вы должны заключить только строку myself$
в CONVERT(varbinary, ...)
.
Код C # должен выглядеть примерно так:
string strUser = "myself$";
int iSession = 131072;
int iContextID = 1234567890;
StringBuilder sb = new StringBuilder();
sb.Append("declare @context_info varbinary(120);");
sb.Append("set @context_info = 0x");
sb.Append(iSession.ToString("X8"));
sb.Append(";");
sb.Append("set @context_info = @context_info + 0x");
sb.Append(iContextID.ToString("X8"));
sb.Append(";");
sb.Append("set @context_info = @context_info + CONVERT(varbinary(120), N'");
sb.Append(strUser);
sb.Append("');");
sb.Append("set context_info @context_info;");
string strContext = sb.ToSTring();
SqlCommand scContext = new SqlCommand(strContext, conn, tran);
scContext.ExecuteNonQuery();
См. Также C # convert integerзаговорить и обратно