当 where 子句中有变量时,无法从 nvarchar 转换为 int
Cannot convert from nvarchar to int when there are variables in where clause
select @now_total = COUNT(*)
from CountTable
where quotename(CHAR(65 + @i - 1)) > 0 ;
我在SQL服务器中写这个是为了得到列'A'、B'...'Z'中的值分别大于0的行数。但是 SQL 服务器告诉我
cannot convert from nvarchar to int
我尝试将 quotename
更改为 [A]>0
,没关系。但我必须计算 i=1...26。正确的说法是什么?
谢谢!
您不能在这样的 SQL 语句中间动态指定列名。
你可以构造一个包含SQL语句的字符串然后执行它:
declare @now_total int
declare @sql nvarchar(max)
set @sql =
'select @now_total = count(*) from CountTable where ' + quotename(char(64+@i)) + ' > 0;'
exec sp_executesql @sql, N'@now_total int output', @now_total output;
如您所见,这并不好玩。
最好将 table 结构从
更改为
create table CountTable (A int, B int, C int, ...)
insert CountTable values (1, 34, 0, ..)
类似于
create table CountTable (CountId int, ValueId char(1), Count int)
insert CountTable values (1, 'A', 1)
insert CountTable values (1, 'B', 34)
insert CountTable values (1, 'C', 0)
...
那么你的查询就变成了
select count(distinct CountId) from CountTable where ValueId=char(64+@i) and Count>0
而且您不必使用动态 SQL。
这是因为您不能使用普通 SQL 动态指定列。这里发生的是 quotename(CHAR(65))
被转换为 [A]
。但不是使用列 A
,而是将其视为文字。因此,错误:
Conversion failed when converting the nvarchar value '[A]' to data
type int.
你应该使用动态 sql:
CREATE TABLE tbl(
ID INT IDENTITY(1, 1),
A INT,
B INT
)
INSERT INTO tbl(A, B) VALUES
(1, 1), (1, 2), (2, 2), (2, 3);
DECLARE @now_total INT
DECLARE @i INT = 1
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT @now_total = COUNT(*) FROM tbl WHERE ' + QUOTENAME(CHAR(65 + @i - 1) ) + ' > 0'
EXEC sp_executesql @sql, N'@now_total INT OUT', @now_total OUT
SELECT @now_total
DROP TABLE tbl
select @now_total = COUNT(*)
from CountTable
where quotename(CHAR(65 + @i - 1)) > 0 ;
我在SQL服务器中写这个是为了得到列'A'、B'...'Z'中的值分别大于0的行数。但是 SQL 服务器告诉我
cannot convert from nvarchar to int
我尝试将 quotename
更改为 [A]>0
,没关系。但我必须计算 i=1...26。正确的说法是什么?
谢谢!
您不能在这样的 SQL 语句中间动态指定列名。
你可以构造一个包含SQL语句的字符串然后执行它:
declare @now_total int
declare @sql nvarchar(max)
set @sql =
'select @now_total = count(*) from CountTable where ' + quotename(char(64+@i)) + ' > 0;'
exec sp_executesql @sql, N'@now_total int output', @now_total output;
如您所见,这并不好玩。
最好将 table 结构从
更改为create table CountTable (A int, B int, C int, ...)
insert CountTable values (1, 34, 0, ..)
类似于
create table CountTable (CountId int, ValueId char(1), Count int)
insert CountTable values (1, 'A', 1)
insert CountTable values (1, 'B', 34)
insert CountTable values (1, 'C', 0)
...
那么你的查询就变成了
select count(distinct CountId) from CountTable where ValueId=char(64+@i) and Count>0
而且您不必使用动态 SQL。
这是因为您不能使用普通 SQL 动态指定列。这里发生的是 quotename(CHAR(65))
被转换为 [A]
。但不是使用列 A
,而是将其视为文字。因此,错误:
Conversion failed when converting the nvarchar value '[A]' to data type int.
你应该使用动态 sql:
CREATE TABLE tbl(
ID INT IDENTITY(1, 1),
A INT,
B INT
)
INSERT INTO tbl(A, B) VALUES
(1, 1), (1, 2), (2, 2), (2, 3);
DECLARE @now_total INT
DECLARE @i INT = 1
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT @now_total = COUNT(*) FROM tbl WHERE ' + QUOTENAME(CHAR(65 + @i - 1) ) + ' > 0'
EXEC sp_executesql @sql, N'@now_total INT OUT', @now_total OUT
SELECT @now_total
DROP TABLE tbl