【问题标题】:Implicit conversion - SQL隐式转换 - SQL
【发布时间】:2021-06-06 02:12:24
【问题描述】:

我有以下 SQL 查询

DECLARE @table table(dbname sysname)

INSERT INTO @table(dbname)
SELECT NAME FROM sys.databases where name like '%AccountsLive'

DECLARE @Sql NVARCHAR(MAX) = NULL;

SELECT  @Sql = COALESCE(@Sql + ' UNION ALL ' + CHAR(13) + CHAR(10), '' ) +
'SELECT ST_ALOC_POINTER, ST_TRANTYPE, ST_HEADER_REF, ST_GROSS , ST_CURRENCYCODE , ST_CURR_VALU , ST_DESCRIPTION FROM ' 
+ QUOTENAME(dbname) + '.dbo.SL_TRANSACTIONS
WHERE ST_YEAR = ''N''
and ST_PERIODNUMBER = ''1''
and ST_ALOC_POINTER like ''%LC%''
and ST_GROSS <> ''0''
UNION ALL
SELECT ST_ALOC_POINTER, ST_TRANTYPE, ST_HEADER_REF, ST_GROSS , ST_CURRENCYCODE , ST_CURR_VALU , ST_DESCRIPTION FROM ' 
+ QUOTENAME(dbname) + '.dbo.SL_TRANSACTIONS
WHERE ST_YEAR = ''N''
and ST_PERIODNUMBER = ''1''
and ST_ALOC_POINTER like ''%CR%''
and ST_GROSS <> ''0'''
FROM    @table

EXEC( @Sql );

但是,我收到如下隐式转换错误:

无法执行 varchar 值到 varchar 的隐式转换,因为 UNION ALL 运算符中的“SQL_Latin1_General_CP1_CI_AS”和“Latin1_General_CI_AS”之间的排序规则冲突导致值的排序规则未解决。

有谁知道这是什么或如何解决我的查询?提前致谢!

【问题讨论】:

  • 请打印@sql 并发布它以查看生成的查询。
  • 整张照片太长了,这里放不下,所以这里只是第一部分:SELECT ST_ALOC_POINTER, ST_TRANTYPE, ST_HEADER_REF, ST_GROSS , ST_CURRENCYCODE , ST_CURR_VALU , ST_DESCRIPTION FROM [MADAccountsLive].dbo.SL_TRANSACTIONS WHERE ST_YEAR = 'N' and ST_PERIODNUMBER = '1' and ST_ALOC_POINTER like '%LC%' and ST_GROSS &lt;&gt; '0' UNION ALL
  • 这是简单的 SQL 调试...首先打印 SQL 并将其作为静态 SQL 运行...比动态调试更容易。其次删除所有列并一次加回1,直到发生错误,正确整理导致错误的列...将修复程序放回动态SQL中。这不是我们可以查看和回答的问题,因为我们不知道您的列的排序规则。
  • @DaleK 感谢您的建议,并在下面的帮助下完成了这项工作,现在完美运行!

标签: sql-server tsql dynamic-sql


【解决方案1】:

错误是关于您的表和 sys.databases 表的排序规则不同,您应该在 select 语句中使用显式排序规则(问题是 dbname),然后更改这一行:

SELECT NAME COLLATE Latin1_General_CI_AS FROM sys.databases where name like '%AccountsLive'

并将您的 @table 更改为:

DECLARE @table table(dbname sysname COLLATE Latin1_General_CI_AS)

如果不能解决问题,也请使用这个:

... QUOTENAME(dbname) COLLATE Latin1_General_CI_AS ... 

【讨论】:

  • 我尝试这个时仍然得到相同的隐式转换错误:(如果我将它与@venkataraman 解决方案结合起来,我会得到相同的表达式类型浮点错误
  • 我在我的代码中使用它,但答案更新了,在@venkataraman 答案中使用 collat​​e 仅用于 varchar 列。
  • 感谢您的帮助,非常感谢.....我已将其与 @venkataraman 一起使用,现在一切正常
  • 要补充的一点是,我需要给每一列一个别名,否则我会得到一个“无列名”的结果
【解决方案2】:

当我们将 UNION ALL 放在多个数据库中时,我们遇到了排序规则错误,因为数据库表中的列之间存在排序规则冲突。

为避免这种情况,我们可以针对有问题的特定列修改下面给出的查询。

我们不需要对每一列都这样做。但是,由于我不知道哪个列存在此问题,因此我将查询中的所有列都放入。

SELECT  @Sql = COALESCE(@Sql + ' UNION ALL ' + CHAR(13) + CHAR(10), '' ) +
'SELECT ST_ALOC_POINTER COLLATE DATABASE_DEFAULT, ST_TRANTYPE COLLATE DATABASE_DEFAULT,
 ST_HEADER_REF COLLATE DATABASE_DEFAULT, ST_GROSS COLLATE DATABASE_DEFAULT, 
ST_CURRENCYCODE COLLATE DATABASE_DEFAULT, ST_CURR_VALU COLLATE DATABASE_DEFAULT, 
ST_DESCRIPTION COLLATE DATABASE_DEFAULT FROM ' 
+ QUOTENAME(dbname) + '.dbo.SL_TRANSACTIONS

【讨论】:

  • 我现在正在使用这个Expression type float is invalid for COLLATE clause.
  • @PeterK 仅将COLLATE 用于字符串列,例如varchar
  • 非常感谢您在这方面的帮助....我现在可以正常工作了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
相关资源
最近更新 更多