【发布时间】:2019-07-13 01:54:30
【问题描述】:
该函数正在寻求返回一个整数值,该整数值等于列中出现在零之前的值的总和,并将其添加到列中的最终值。
CREATE FUNCTION name
(@p1 NVARCHAR(MAX),
@p2 INT,
@p3 INT)
RETURNS INT
AS
BEGIN
DECLARE @total INT = 0
DECLARE @cnt INT = 1;
DECLARE @row INT = 0
DECLARE @nextRow INT = 0;
DECLARE @tmp NVARCHAR(MAX)
SET @tmp = @p1
DECLARE @myTemp TABLE (Col INT, ID1 INT, ID2 INT, reading NVARCHAR(MAX));
DECLARE @zeroCols TABLE(rn INT, Col INT);
INSERT INTO @myTemp
SELECT ROW_NUMBER() OVER(ORDER BY nHeatID) Col, col2, col3, @tmp
FROM schema.table
WHERE col4 = @p2
AND col5 = @p3
SET @total = (SELECT TOP 1 @tmp FROM @myTemp ORDER BY col DESC)
INSERT INTO @zeroCols
SELECT ROW_NUMBER() OVER(ORDER BY col) rn, col
FROM @myTemp
WHERE @tmp = 0
WHILE @cnt <= (SELECT COUNT(Col) FROM @zeroCols)
BEGIN
SET @row = (SELECT Col FROM @zeroCols WHERE rn = @cnt)
IF ((SELECT @tmp FROM @myTemp WHERE col = @row-1) <> 0)
SET @total = @total + (SELECT @tmp FROM @myTemp WHERE col = @row-1);
SET @cnt = @cnt + 1;
END;
RETURN @total
END;
@myTemp 表将我的表中的数据与行号放在一起,@zeroCols 表将行号放在零所在的位置。
然后我遍历该组值并确定在提供的列的零之前是否有一个非零值,如果有,我将其添加到总数中。
这在我尝试将它变成一个函数之前就已经奏效了。
难道不喜欢我将nvarchar 作为列名传递吗?
当我这样称呼它时:
SELECT name('val', 0, 0)
我收到此错误:
将 nvarchar 值 'val' 转换为数据类型 int 时转换失败
【问题讨论】:
-
我们在这里遗漏了真正重要的部分...函数的 DDL。
-
欢迎来到 SO。如果您提供代码肯定会有所帮助。显然,您在代码中的某处使用了@p1,它被转换(可能是隐式地)转换为 int。注意 int 的优先级比 text 高,所以如果你把它和其他 int 的地方混在一起,它会尝试改变它。通常在您尝试打印某些内容时发生。
-
错误在
...function body...。我们需要看到那部分。 -
问题不在于将'val'强制转换为nvarchar(max)的参数数据类型,问题是在@p1作为int内部使用功能体。我敢打赌,如果你传递值 '1' 而不是 'val' 你不会得到错误。
-
当一些没有经验的开发人员尝试将具有
int数据类型的列/变量与列/变量/硬编码的 varchar/nvarchar 进行比较时,会发生 100 次中的 99 次。原因是 SQL Server 会尝试将字符串值隐式转换为 int 值。没有看到函数的代码,不可能给出更准确的答案。
标签: sql sql-server tsql