在没有引号的函数中传递值 T-SQL / SQL Server 2012?
Passing value in a function without quote T-SQL / SQL Server 2012?
我在 SQL Server 2012 中创建的一个函数需要帮助,该函数用于检查输入值。如果函数检测到数字 - return 0,如果检测到字符 return 1.
但是对于同一个数字,我得到了 2 个不同的结果,有引号和没有引号。
select dbo.IS_ALIEN('56789')
returns 0
select dbo.IS_ALIEN(56789)
returns 1(我需要return0)
这是我的功能:
ALTER FUNCTION [dbo].[IS_ALIEN]
(@alienNAIC CHAR(1))
RETURNS NUMERIC(10,0)
AS
BEGIN
DECLARE @nNum NUMERIC(1,0);
BEGIN
SET @NnUM = ISNUMERIC(@alienNAIC)
END
BEGIN
IF @nNum = 1
RETURN 0;
END
RETURN 1;
END
相同的概念:
select dbo.IS_ALIEN('AA-11990043')
returns 1
或
select dbo.IS_ALIEN(NULL)
returns 1(我需要它return0)
我正在使用 Oracle 函数参考(以下代码只是旧数据库的参考):
create or replace FUNCTION "IS_ALIEN"
( alienNAIC IN char )
RETURN NUMBER IS
nNum number;
BEGIN
SELECT MOD(alienNAIC, 2) into nNum FROM dual;
return 0;
EXCEPTION
WHEN INVALID_NUMBER THEN
return 1;
END;
但是T-SQL函数不允许错误异常。所以我尽量转换得更近一些。
我建议你使用类似这样的东西(我已经将其缩减了一些):
ALTER FUNCTION [dbo].[IS_ALIEN](@alienNAIC NVARCHAR(10))
RETURNS INT -- NOTE: You could also return tinyint or bit
AS
BEGIN
IF ISNUMERIC(@alienNAIC) = 1
RETURN 0;
RETURN 1;
END
您尝试的问题是存在对 CHAR(1)
的隐式转换,其结果绝对不是@Joel 指出的数字:
SELECT CAST(0 As CHAR(1)) -- returns character '0', ISNUMERIC(0) = 1
SELECT CAST(9 As CHAR(1)) -- returns character '9', ISNUMERIC(0) = 1
SELECT CAST(12345 As CHAR(1)) -- any number over 9 returns character '*', ISNUMERIC(12345) = 0
这是一个我以前从未见过的奇怪的隐式转换案例。通过使参数成为 NVARCHAR
(假设未来可能的双字节输入),字符串将被正确检查并且传入的整数将被隐式转换为 NVARCHAR
,并且 ISNUMERIC
检查将成功.
编辑
重新阅读问题和评论,您似乎想要识别特定的字符串语法以确定某些内容是否为 "alien" 。如果您愿意 更改业务逻辑以修复明显较差的遗留实现 ,您可以考虑这样的事情:
ALTER FUNCTION [dbo].[temp](@alienNAIC NVARCHAR(10))
RETURNS INT -- NOTE: You could also return tinyint or bit
AS
BEGIN
IF @alienNAIC like 'AA-%' AND ISNUMERIC(RIGHT(@alienNAIC, LEN(@alienNAIC) - 3)) = 1
RETURN 1; -- notice this is now 1 instead of 0, we're doing a specific check for 'AA-nnnnn...'
RETURN 0;
END
请注意,如果要与遗留数据进行交互,应该针对遗留数据对其进行彻底测试——您永远不知道编写不当的遗留系统留下了哪些垃圾数据。解决这个问题很可能会破坏其他东西。如果您确实进行了此更改,请将其记录下来。
如果您只需要检查第一个字符,那么您可以这样做:
CREATE FUNCTION [dbo].[IS_ALIEN]
(@alienNAIC VARCHAR(200))
RETURNS TINYINT
AS
BEGIN
IF LEFT(@alienNAIC,1) BETWEEN '0' AND '9' RETURN 1;
RETURN 0
END
GO
您似乎在尝试检查字符串是否以非数字字符开头。可以使用 LIKE 执行此类模式匹配,例如
declare @var nvarchar(10)='A56789'
select
case when @var LIKE '[0-9]%'
then 0 else 1
end AS IsAlien
Returns
1
declare @var nvarchar(10)=56789
和 declare @var int=56789
return 0 因为数字被隐式转换为字符串。
表达式很短,您可能不需要将其转换为函数。如果你这样做,它可以很简单:
create FUNCTION [dbo].[IS_ALIEN] (@alienNAIC varchar(200))
RETURNS INT
begin
return case when @alienNAIC LIKE '[0-9]%'
then 0 else 1
end
end
如果要在 WHERE 子句中执行检查,只需使用 LIKE
,而不是任何函数,例如:
WHERE alienNAIC NOT LIKE '[0-9]%'
这个特定的模式只是一个范围搜索,涵盖了 0
和 9......
之间的所有值。服务器可以使用覆盖文本列的索引来快速识别匹配项。当它必须检查函数的 result 时,它不能这样做。它必须在过滤之前计算每一行的值。
我在 SQL Server 2012 中创建的一个函数需要帮助,该函数用于检查输入值。如果函数检测到数字 - return 0,如果检测到字符 return 1.
但是对于同一个数字,我得到了 2 个不同的结果,有引号和没有引号。
select dbo.IS_ALIEN('56789')
returns 0
select dbo.IS_ALIEN(56789)
returns 1(我需要return0)
这是我的功能:
ALTER FUNCTION [dbo].[IS_ALIEN]
(@alienNAIC CHAR(1))
RETURNS NUMERIC(10,0)
AS
BEGIN
DECLARE @nNum NUMERIC(1,0);
BEGIN
SET @NnUM = ISNUMERIC(@alienNAIC)
END
BEGIN
IF @nNum = 1
RETURN 0;
END
RETURN 1;
END
相同的概念:
select dbo.IS_ALIEN('AA-11990043')
returns 1
或
select dbo.IS_ALIEN(NULL)
returns 1(我需要它return0)
我正在使用 Oracle 函数参考(以下代码只是旧数据库的参考):
create or replace FUNCTION "IS_ALIEN"
( alienNAIC IN char )
RETURN NUMBER IS
nNum number;
BEGIN
SELECT MOD(alienNAIC, 2) into nNum FROM dual;
return 0;
EXCEPTION
WHEN INVALID_NUMBER THEN
return 1;
END;
但是T-SQL函数不允许错误异常。所以我尽量转换得更近一些。
我建议你使用类似这样的东西(我已经将其缩减了一些):
ALTER FUNCTION [dbo].[IS_ALIEN](@alienNAIC NVARCHAR(10))
RETURNS INT -- NOTE: You could also return tinyint or bit
AS
BEGIN
IF ISNUMERIC(@alienNAIC) = 1
RETURN 0;
RETURN 1;
END
您尝试的问题是存在对 CHAR(1)
的隐式转换,其结果绝对不是@Joel 指出的数字:
SELECT CAST(0 As CHAR(1)) -- returns character '0', ISNUMERIC(0) = 1
SELECT CAST(9 As CHAR(1)) -- returns character '9', ISNUMERIC(0) = 1
SELECT CAST(12345 As CHAR(1)) -- any number over 9 returns character '*', ISNUMERIC(12345) = 0
这是一个我以前从未见过的奇怪的隐式转换案例。通过使参数成为 NVARCHAR
(假设未来可能的双字节输入),字符串将被正确检查并且传入的整数将被隐式转换为 NVARCHAR
,并且 ISNUMERIC
检查将成功.
编辑 重新阅读问题和评论,您似乎想要识别特定的字符串语法以确定某些内容是否为 "alien" 。如果您愿意 更改业务逻辑以修复明显较差的遗留实现 ,您可以考虑这样的事情:
ALTER FUNCTION [dbo].[temp](@alienNAIC NVARCHAR(10))
RETURNS INT -- NOTE: You could also return tinyint or bit
AS
BEGIN
IF @alienNAIC like 'AA-%' AND ISNUMERIC(RIGHT(@alienNAIC, LEN(@alienNAIC) - 3)) = 1
RETURN 1; -- notice this is now 1 instead of 0, we're doing a specific check for 'AA-nnnnn...'
RETURN 0;
END
请注意,如果要与遗留数据进行交互,应该针对遗留数据对其进行彻底测试——您永远不知道编写不当的遗留系统留下了哪些垃圾数据。解决这个问题很可能会破坏其他东西。如果您确实进行了此更改,请将其记录下来。
如果您只需要检查第一个字符,那么您可以这样做:
CREATE FUNCTION [dbo].[IS_ALIEN]
(@alienNAIC VARCHAR(200))
RETURNS TINYINT
AS
BEGIN
IF LEFT(@alienNAIC,1) BETWEEN '0' AND '9' RETURN 1;
RETURN 0
END
GO
您似乎在尝试检查字符串是否以非数字字符开头。可以使用 LIKE 执行此类模式匹配,例如
declare @var nvarchar(10)='A56789'
select
case when @var LIKE '[0-9]%'
then 0 else 1
end AS IsAlien
Returns
1
declare @var nvarchar(10)=56789
和 declare @var int=56789
return 0 因为数字被隐式转换为字符串。
表达式很短,您可能不需要将其转换为函数。如果你这样做,它可以很简单:
create FUNCTION [dbo].[IS_ALIEN] (@alienNAIC varchar(200))
RETURNS INT
begin
return case when @alienNAIC LIKE '[0-9]%'
then 0 else 1
end
end
如果要在 WHERE 子句中执行检查,只需使用 LIKE
,而不是任何函数,例如:
WHERE alienNAIC NOT LIKE '[0-9]%'
这个特定的模式只是一个范围搜索,涵盖了 0
和 9......
之间的所有值。服务器可以使用覆盖文本列的索引来快速识别匹配项。当它必须检查函数的 result 时,它不能这样做。它必须在过滤之前计算每一行的值。