运行此查询时出现错误,因为数据类型money无法隐式转换为varchar。但是,在尝试转换之前,我正在使用if statemnt来确保数据类型不是钱。显然,无论如何都要执行转换。谁知道为什么?
表:BBH_NEW col: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
错误:
Msg 257,Level 16,State 3,Line 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'
答案 0 :(得分:2)
据我所知,当您收到错误时,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';
答案 1 :(得分:0)
优化发电机的一些提示
重写
SELECT @hold =
'if '''+@temp+'''= ''money''
begin
...
end
as
if @temp = 'money'
begin
...
end
其次,我不能想到
时的情况[rebate2] IS NOT NULL
并不意味着
len(CONVERT(VARCHAR(8000), [rebate2])) > 0
换句话说,只要rebate2不为NULL,其字符串长度就会大于0