我在下面要问的是:此SQL函数的@cleartext参数的实际数据类型是什么? >> ENCRYPTBYKEY(..) - http://msdn.microsoft.com/en-us/library/ms174361.aspx
(如果您在此行下方阅读,则可以按照历史和推理进行操作。我认为它比首次出现时更棘手。)
SQL Server文档声明EncryptByKey(..)函数的 @cleartext(2nd)参数可以接受多种类型:
EncryptByKey(@key_GUID, @cleartext [,@ add_authenticator,@ authenticator])
@cleartext
是类型的变量 nvarchar,char,varchar,binary, 包含数据的varbinary或nchar 用密钥加密。
^ ^ ^ ^ ^ ^ ^ ^ ^ - - - - - 但它的实际声明数据类型是什么? ...
如果我要创建一个自定义函数(完全独立于上面给出的EncryptByKey示例)我给出了一个自定义参数的实际数据类型,以便它以相同的方式接受所有相同的类型?
编辑1:我实际上是在自定义中包装SQL EncryptByKey函数 UDF功能,我想重新创建相同的功能 要传递给的参数类型 它。这就是我想要按类型创建完全相同的参数的原因。
修改2 :如果我尝试使用sql_variant
,则会导致错误
Msg 8116,Level 16,State 1,Procedure EncryptWrapper,第17行参数数据 类型sql_variant对于无效 EncryptByKey函数的参数2。
编辑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 param使用正确的数据类型。
编辑4 :发现EncryptByKey(..)@cleartext参数不是以下类型:
sql_variant
- 传递时出现错误varbinary
- 限制性太强 - 不允许传递EncryptByKey(..)否则接受的文本类型sysname
,nvarchar
,varchar
- 奇怪的行为 - 往往只接受参数文字的第一个字符或其他内容答案 0 :(得分:2)
尝试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转换回本机数据类型
修改强>
这是一个如何获取原始数据类型的示例:
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)
答案 1 :(得分:0)
ENCRYPTBYKEY()几乎肯定不是用vanilla T-SQL编写的。它不需要遵循T-SQL数据类型规则。
也就是说,如果你想为它编写一个包装器,请使用SQL_VARIANT作为@cleartext参数,就像KM建议的那样。
如果ENCRYPTBYKEY()对@cleartext的最大长度不敏感,则可以将所有CHAR / VARCHAR复制到VARCHAR(8000),将所有NCHAR / NVARCHAR复制到NVACHAR(4000)。
否则你可能是SOL:任何尊重最大长度的数据类型转换 - 例如,CHAR(10)vs CHAR(20) - 都需要动态SQL,所以你必须把它写成一个存储过程,而不是而不是一个功能。那时,它不再是一个包装器了。