sql server 条件
Posted
技术标签:
【中文标题】sql server 条件【英文标题】:sql server conditionals 【发布时间】:2010-02-26 19:30:20 【问题描述】:运行此查询时出现错误,因为数据类型 money 无法隐式转换为 varchar。但是,在尝试转换之前,我使用 if 语句来确保数据类型不是金钱。显然,无论如何都在执行转换。有人知道为什么吗?
表:BBH_NEW 列:rebate2 数据类型:钱
if 'money'= 'money'
begin
if (select max([rebate2]) from [BBH_NEW]) = 0
and (select min([rebate2]) from [BBH_NEW]) = 0
print ' rebate2 '
print ' 1 '
end
if 'money'!= 'money'
begin
IF NOT EXISTS (SELECT top 1 * FROM [BBH_NEW] WHERE [rebate2] IS NOT NULL and
len([rebate2]) > 0 )
BEGIN
print ' rebate2 '
end
end
错误: 消息 257,第 16 级,状态 3,第 11 行 不允许从数据类型 money 到 varchar 的隐式转换。使用 CONVERT 函数运行此查询。
是的,此代码已生成。如果有帮助,这是用于生成它的代码:
select @temp =
data_type FROM information_schema.columns
WHERE table_schema = 'dbo'
AND table_name = @tblname
AND column_name = @col
SELECT @hold =
'if '''+@temp+'''= ''money''
begin
if (select max(['+@col+']) from ['+@tblname+']) = 0
and (select min(['+@col+']) from ['+@tblname+']) = 0
print '' '+@col+' money''
end
if '''+@temp+'''!= ''money''
begin
IF NOT EXISTS (SELECT max([' + @col + ']) FROM ['+ @tblname + ']
WHERE len( [' + @col + ']) > 0 )
BEGIN
print '' ' + @col + ' ''
end
end'
【问题讨论】:
什么时候字符串'money'不等于自己? 此代码是动态生成的。它通常不是 'money' != 'money' ,它使用当前列数据类型。即如果'varchar'!='钱'。我使用这个例子是因为它试图告诉我事实上 'money' != 'money' 因为它正在执行下一行 那么提供的代码实际上是生成并产生了错误?我在 SSMS 2008 中运行它,它运行时没有任何缺陷。 我在 SSMS 2008 中运行它并得到错误。源代码见上面的编辑 if '''+@temp+'''!= ''money'': 不应该是 ''money'' 吗? 【参考方案1】:据我了解,当您收到错误时,列 BBH_NEW.rebate2 的类型为 money
。在 T-SQL 中,您不能有一个无法编译的查询,这就是您所遇到的。即使 always-false if 块中的查询不会运行,它也不会编译,因为数据类型不匹配。
首先,为您提供一个快速解决方案 - 使用 CONVERT 或 CAST 显式更改数据类型。
if 'money'!= 'money'
begin
IF NOT EXISTS (SELECT top 1 * FROM [BBH_NEW] WHERE [rebate2] IS NOT NULL and
len(CONVERT(VARCHAR(8000), [rebate2])) > 0 )
BEGIN
print ' rebate2 '
end
end
但是,必须有更好的方法来完成您正在做的任何事情......该 SQL 何时生成?如果是在运行时,你可以不生成不会运行的部分吗?也许是这样的?
SELECT @hold = CASE WHEN @temp = 'money' THEN
'if (select max(['+@col+']) from ['+@tblname+']) = 0
and (select min(['+@col+']) from ['+@tblname+']) = 0
print '' '+@col+' money'''
ELSE
'IF NOT EXISTS (SELECT max([' + @col + ']) FROM ['+ @tblname + ']
WHERE len( [' + @col + ']) > 0 )
BEGIN
print '' ' + @col + ' ''
end'
END
或者也许将世代改为这个......
SELECT @temp = DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = @tblname
AND COLUMN_NAME = @col
IF(@temp = 'money')
SELECT @hold = 'IF(EXISTS(
SELECT 1
FROM ['+@tblname+']
HAVING MAX(['+@col+']) = 0
AND MIN(['+@col+']) = 0))
BEGIN
PRINT '' '+@col+' ''
END';
ELSE
SELECT @hold = 'IF(NOT EXISTS(
SELECT *
FROM ['+@tblname+']
WHERE ['+@col+'] IS NOT NULL
AND LEN(['+@col+']) > 0))
BEGIN
PRINT '' '+@col+' ''
END';
【讨论】:
谢谢,我没有意识到错误来自编译 vs 在运行时【参考方案2】:一些优化生成器的提示
重写
SELECT @hold =
'if '''+@temp+'''= ''money''
begin
...
end
作为
if @temp = 'money'
begin
...
end
第二,我想不出什么时候
[rebate2] IS NOT NULL
不暗示
len(CONVERT(VARCHAR(8000), [rebate2])) > 0
也就是说,只要rebate2不为NULL,它的字符串长度就大于0
【讨论】:
"也就是说,只要rebate2不为NULL,它的字符串长度就大于0" 不,SQL Server区分空字符串''和null。 @Shannon Severance 其中 MONEY NOT NULL 值表示空字符串。 你是对的。我说话没有考虑清楚。以上是关于sql server 条件的主要内容,如果未能解决你的问题,请参考以下文章
将 Crystal Reports 条件转换为 SQL Server 条件