SQL insert into SELECT from函数返回相同的值

SQL insert into SELECT from函数返回相同的值,sql,sql-server,user-defined-functions,Sql,Sql Server,User Defined Functions,我有以下函数,它根据@Date的月份返回新代码 CREATE FUNCTION [dbo].[NewCode](@Date date) RETURNS nvarchar(4) AS BEGIN DECLARE @LastCode nvarchar(4); SET @LastCode = (SELECT MAX(Code) FROM TABLE1 WHERE MONTH(TDate) = MONTH(@Date)) IF @LastCode IS NULL

我有以下函数,它根据@Date的月份返回新代码

CREATE FUNCTION [dbo].[NewCode](@Date date)
    RETURNS nvarchar(4) AS
    BEGIN
    DECLARE @LastCode nvarchar(4);
    SET @LastCode = (SELECT MAX(Code) FROM TABLE1 WHERE MONTH(TDate) = MONTH(@Date))
    IF @LastCode IS NULL
        SET @LastCode = '0001';
    ELSE
        BEGIN
            SET @LastCode = CONVERT(nvarchar,(CONVERT(int, @LastCode) + 1));
            WHILE LEN(@LastCode) < 4
                BEGIN
                    SET @LastCode = '0' + @LastCode;
                END
        END

            RETURN @LastCode;
    END
如何使此函数按行计算而不是按查询计算


谢谢。

我不确定这是否是对您问题的准确回答,我也不知道这是否是最好的方法,但我认为这可能会解决您的问题。只需为每个选定行生成值(使用
row\u NUMBER()
)并将该值添加到函数的结果中即可。函数被更改并返回整数值

CREATE FUNCTION [dbo].[NewCode] (
    @Date date
)
RETURNS numeric(4, 0) AS
BEGIN
    DECLARE @LastCode numeric(4, 0);
    SET @LastCode = (SELECT MAX(Code) FROM TABLE1 WHERE MONTH(TDate) = MONTH(@Date))
    IF @LastCode IS NULL 
        SET @LastCode = 1;
    ELSE
        SET @LastCode = CONVERT(int, @LastCode) + 1;
    RETURN @LastCode;
END

INSERT INTO Table1 
SELECT 
    T1, T2, T3, 
    RIGHT('0000' + CAST(dbo.NewCode(Table2.TDate) + ROW_NUMBER() OVER (ORDER BY T1) - 1 AS varchar(4)), 4)
    FROM Table2

由于您正在使用表2的日期列在表1中插入数据,只需检查表2中不同月份的日期值。您的函数对于每一行都能很好地工作。

dbo.NewCode()
是一个标量函数,因此它将在每一行执行。可能需要检查几件事情。首先,从表1中选择所有代码值,并确保它们都有4个字符长。“0034”、“1000”、“33”的值将选择33作为最大值。如果数据正常,请检查排序规则。如果可以,将数字存储为数字以克服可能出现的问题,如上面的“排序”,我怀疑您遇到的问题是希望每个插入的行都包含在函数所做的计算中。因此,如果插入了一行代码为34的新代码,那么您希望当月的下一行代码为35,但它也被设置为34。您可以使用某种
ROW\u NUMBER()
函数,并将其值添加到
NewCode
函数中的数字中。这是个坏主意。只需使用一个
标识
,然后将其转换为您喜欢的标识符。
INSERT INTO Table1 SELECT T1, T2, T3, dbo.NewCode(Table2.TDate) FROM Table2