Каков фактический тип данных параметра @cleartext (2nd) функции EncryptByKey (..) SQL Server? - PullRequest
2 голосов
/ 17 февраля 2010

Что я спрашиваю ниже: Что такое фактический тип данных параметра @cleartext этой функции SQL?>> ENCRYPTBYKEY (..) - http://msdn.microsoft.com/en-us/library/ms174361.aspx

(Если вы читаете ниже этой строки, вы можете следить за историей и рассуждениями. Я думаю, что это сложнее, чем кажется на первый взгляд.)


Документация по SQL Server гласит, что параметр @ cleartext (2nd) EncryptByKey (..) функция может принимать различные типы:

EncryptByKey (@key_GUID, @ cleartext [, @add_authenticator, @authenticator])

@ cleartext Переменная типа nvarchar, char, varchar, binary, varbinary или nchar , содержащая данные, которые должны быть зашифрованы с помощью ключа.

^ ^ ^^ ^ ^ ^ ^ ^ ^ - - - - - Но каков фактически объявленный тип данных?...

Если бы я должен был создать пользовательскую функцию (полностью отделенную от приведенного выше примера EncryptByKey) какой фактический тип данных мне дать пользовательский параметр, чтобы он принимал все те жевводить таким же образом?

Редактировать 1: Я фактически обертываю функцию SQL EncryptByKey в пользовательскую функцию UDF, и я хочу воссоздать те же типы параметров, чтобы пройти черезк этому.Это причина того, что я хочу создать точно такие же параметры по типу.

Редактировать 2: Если я попытаюсь использовать sql_variant, это приведет к ошибке

Сообщение 8116, уровень 16, состояние 1, процедура EncryptWrapper, строка 17 Тип данных аргумента sql_variant недопустим для аргумента 2 функции EncryptByKey.

Редактировать 3:

Вот моя пользовательская функция-обертка - и прямая проблема.Каким должен быть тип данных @cleartext для прямого доступа к EncryptByKey?

ALTER FUNCTION [dbo].[EncryptWrapper]
(
 @key_GUID uniqueidentifier,
 @cleartext -- ???????????  <<< WHAT TYPE ????????????????
 @add_authenticator int = 0,
 @authenticator sysname = NULL
)
RETURNS varbinary(8000)
AS
BEGIN

    -- //Calling a SQL Server builtin function. 
    -- //Second param @cleartext is the problem. What data type should it be?
 Return EncryptByKey(@key_GUID, @cleartext, @add_authenticator, @authenticator)

END

Примечание: мне не нужно было использовать CAST или CONVERT - мне нужно только использовать правильный тип данных для моего параметра @cleartext.

Редактировать 4 : Обнаружен параметр EncryptByKey (..) @cleartext , а не следующих типов :

  • sql_variant - выдает ошибку при передаче
  • varbinary- слишком ограничительный - не разрешает передавать типы текста, принятые в противном случае EncryptByKey (..)
  • sysname, nvarchar, varchar - странное поведение, как правило, принимает только первый символтекст аргумента или что-то

Ответы [ 2 ]

2 голосов
/ 17 февраля 2010

попробуйте sql_variant:

CREATE FUNCTION [dbo].[yourFunction]
(
     @InputStr      sql_variant   --can not be varchar(max) or nvarchar(max)
)
returns
varchar(8000)

BEGIN
    --can use SQL_VARIANT_PROPERTY(@InputStr,'BaseType') to determine given datatype

    --do whatever you want with @inputStr here
    RETURN CONVERT(varchar(8000),@InputStr)  --key is to convert the sql_varient to something you can use

END
GO

ключ в том, чтобы преобразовать sql_varient во что-то, что вы можете использовать в функции. Вы можете использовать операторы IF, проверить BaseType и преобразовать sql_varient обратно в собственный тип данных

EDIT
Вот пример того, как получить оригинальный тип данных:

CREATE FUNCTION [dbo].[yourFunction]
(
     @InputStr      sql_variant   --can not be varchar(max) or nvarchar(max)
)
returns
varchar(8000)

BEGIN
    DECLARE @Value varchar(50)
    --can use SQL_VARIANT_PROPERTY(@InputStr,'BaseType') to determine given datatype

    --do whatever you want with @inputStr here
    IF @InputStr IS NULL
    BEGIN
        SET @value= 'was null'
    END
    ELSE IF SQL_VARIANT_PROPERTY(@InputStr,'BaseType')='char'
    BEGIN
        --your special code here
        SET @value= 'char('+CONVERT(varchar(10),SQL_VARIANT_PROPERTY(@InputStr,'MaxLength '))+') - '+CONVERT(varchar(8000),@InputStr)
    END
    ELSE IF SQL_VARIANT_PROPERTY(@InputStr,'BaseType')='datetime'
    BEGIN
        --your special code here
        SET @value= 'datetime - '+CONVERT(char(23),@InputStr,121)
    END
    ELSE IF SQL_VARIANT_PROPERTY(@InputStr,'BaseType')='nvarchar'
    BEGIN
        --your special code here
        SET @value= 'nvarchar('+CONVERT(varchar(10),CONVERT(int,SQL_VARIANT_PROPERTY(@InputStr,'MaxLength '))/2)+') - '+CONVERT(varchar(8000),@InputStr)
    END
    ELSE
    BEGIN
        --your special code here
        set @value= 'unknown!'
    END

    RETURN  @value

END
GO

проверить это:

DECLARE @x char(5), @z int, @d datetime, @n nvarchar(27)
SELECT @x='abc',@d=GETDATE(),@n='wow!'
select [dbo].[yourFunction](@x)
select [dbo].[yourFunction](@d)
select [dbo].[yourFunction](@z)
select [dbo].[yourFunction](@n)

тестовый вывод:

-------------------------------------
char(5) - abc  

(1 row(s) affected)


-------------------------------------
datetime - 2010-02-17 15:10:44.017

(1 row(s) affected)


-------------------------------------
was null

(1 row(s) affected)


-------------------------------------
nvarchar(27) - wow!

(1 row(s) affected)
0 голосов
/ 21 февраля 2010

ENCRYPTBYKEY () почти наверняка не написан на ванильном T-SQL. Не нужно следовать правилам типизации данных T-SQL.

Тем не менее, если вы хотите написать обертку для него, используйте SQL_VARIANT для параметра @cleartext, как и предложил KM.

Если ENCRYPTBYKEY () не чувствителен к максимальной длине @cleartext, вы можете переключить все CHAR / VARCHAR на VARCHAR (8000), а все NCHAR / NVARCHAR на NVACHAR (4000).

В противном случае вы можете быть SOL: любое преобразование типа данных, которое учитывает максимальную длину - например, CHAR (10) против CHAR (20) - потребует динамического SQL, поэтому вам придется писать его как хранимую процедуру, а не чем функция. В этот момент он больше не является оберткой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...