Tsql SQL Server';的@cleartext(第二个)参数的实际数据类型是什么;s EncryptByKey(..)函数?

Tsql SQL Server';的@cleartext(第二个)参数的实际数据类型是什么;s EncryptByKey(..)函数?,tsql,types,parameters,Tsql,Types,Parameters,下面我要问的是:这个SQL函数的@cleartext参数的实际数据类型是什么?>>ENCRYPTBYKEY(…)- (如果你在这一行下面阅读,你可以理解历史和推理。我认为这比第一次出现要复杂。) SQL Server文档说明函数的@cleartext(第二)参数可以接受多种类型: EncryptByKey(@key\u GUID,@cleartext[,@add\u authenticator,@authenticator]) @cleartext是类型的变量 nvarchar、char、v

下面我要问的是:这个SQL函数的@cleartext参数的实际数据类型是什么?>>ENCRYPTBYKEY(…)-

(如果你在这一行下面阅读,你可以理解历史和推理。我认为这比第一次出现要复杂。)


SQL Server文档说明函数的@cleartext(第二)参数可以接受多种类型:

EncryptByKey(@key\u GUID,@cleartext[,@add\u authenticator,@authenticator])

@cleartext
是类型的变量 nvarchar、char、varchar、binary、, varbinary,或包含数据的nchar 要用密钥加密的

^^^^^^^^^^^---但其实际声明的数据类型是什么

如果我要创建一个自定义函数(完全独立于上面给出的EncryptByKey示例)我应该给出什么样的实际数据类型的自定义参数,以便它以相同的方式接受所有这些相同的类型?

编辑1:我实际上是在一个自定义的文件中包装SQL EncryptByKey函数 UDF函数,我想重新创建相同的 要传递到的参数类型 信息技术这就是我想要按类型创建完全相同的参数的原因

编辑2:如果我尝试使用
sql\u variant
它会导致错误

Msg 8116,16级,状态1,程序 EncryptWrapper,第17行参数数据 类型sql\u变量对无效 EncryptByKey函数的参数2

编辑3:

这是我的自定义包装器函数——以及直接的问题。对于直接传递到EncryptByKey,@cleartext的数据类型应该是什么

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
ALTER函数[dbo].[EncryptWrapper]
(
@密钥GUID唯一标识符,
@明文--?????尝试sql\u变体:

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变量转换为可以在函数中使用的内容。您可以使用IF语句并检查BaseType,然后将sql变量转换回本机数据类型

编辑
以下是如何获取原始数据类型的示例:

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)
ENCRYPTBYKEY()几乎肯定不是用普通的t-SQL编写的,它不需要遵循t-SQL数据类型规则

这就是说,如果您想为它编写一个包装器,请按照KM的建议为@cleartext参数使用SQL_变量

如果ENCRYPTBYKEY()对@cleartext的最大长度不敏感,则可以将所有CHAR/VARCHAR转换为VARCHAR(8000),将所有NCHAR/NVARCHAR转换为NVACHAR(4000)


否则,您可能是SOL:任何尊重最大长度的数据类型转换——例如,CHAR(10)vs CHAR(20)--将需要动态SQL,因此您必须将其作为存储过程而不是函数来编写。在这一点上,它不再是真正的包装器。

SQL\u变体导致我在问题的“编辑2”中输入的错误消息。我需要执行直接传递,因此我需要与EncryptByKey的第二个参数使用的数据类型完全相同。I've也编辑了我的答案,在包装器函数中,将sql_variant输入参数转换为文本类型,然后再将其传递给EncryptByKey函数。这是解决我的问题的一个办法,而且是合理的。但是真正的问题是我不需要修改数据类型(通过转换或强制转换)但是,要将其直接传递到SQL EncryptByKey函数的第二个参数,该函数接受多种文本数据类型,因此我希望将相同的文本数据类型接受到一个类型中……我在问题中添加了一个Edit 3来显示确切的问题。SQL_变量是一个包装器数据类型。您的char、varchar、nchar等被传递到函数中,但在该参数的函数是sql_变量。EncryptByKey不采用sql_变量数据类型,因此需要将其转换回传递给函数的原始类型。可以使用sql_variant_属性()执行此操作函数。如果您不想这样做,那么使用TSQL无法实现您的目标。您可以研究使用CLR。我明白您的意思,但是@cleartext参数不接受sql\u variant arg;但是它接受多个文本数据类型,因此从逻辑上讲,它必须定义为sql\u variant以外的数据类型。我们都知道仪表是用实际数据类型(隐式或显式)定义的。您知道如何找出该参数的实际数据类型吗?我能够将其封装在多个函数中:EncryptNVarchar(..),EncryptVarchar(..),EncryptNbinary(..)但是我相信你是对的,它不必遵循标准的SQL规则——微软在编写该函数时没有吃自己的狗粮。