【问题标题】:Cannot insert NULL values into column 'USERNAME', table 'tempdb.dbo.#temptable error无法将 NULL 值插入列 'USERNAME'、表 'tempdb.dbo.#temptable 错误
【发布时间】:2016-10-12 03:58:58
【问题描述】:

我有一个 SP。执行时出现错误

无法将值 NULL 插入到列 'USERNAME'、表 'tempdb.dbo.#temptable________________________________________________________________________________________________________0000000002FD';列不允许空值。更新失败。 声明已终止。

下面是我的SP

ALTER PROCEDURE [dbo].[UserReportData] 
                @As_ONDATE Datetime 

                AS 
            BEGIN 
                    DECLARE @REPORTDATE datetime        
                    DECLARE @USERNAME varchar(110)      

            Select * INTO #temptable
        FROM
                    (
                        select  a.CUser_id, b.User_Id, a.U_datetime
                        as REPORTDATE, b.first_Name + ' '  + b.last_name as USERNAME
                        from inward_doc_tracking_trl a inner join user_mst b
                        on a.CUser_id = b.mkey
                        and a.U_datetime >= @As_ONDATE
                ) as x

DECLARE Cur_1 CURSOR
            FOR SELECT CUser_id, User_Id FROM #temptable

                    OPEN Cur_1
                        DECLARE @CUser_id INT
                        DECLARE @User_Id INT
                        FETCH NEXT FROM Cur_1 
                        INTO @CUser_id, @User_Id

                        WHILE (@@FETCH_STATUS = 0)
            BEGIN

                            SELECT @REPORTDATE = U_datetime FROM inward_doc_tracking_trl                        
                            where  U_datetime >= @As_ONDATE                             



                            UPDATE #temptable
                                SET REPORTDATE = @REPORTDATE,
                                    USERNAME = @USERNAME
                                WHERE CUser_id = @CUser_id
                                AND User_Id = @User_Id  


                FETCH NEXT FROM Cur_1 INTO @CUser_id, @User_Id
                    END
            CLOSE Cur_1
            DEALLOCATE Cur_1


            SELECT * FROM #temptable
                        DROP TABLE #temptable                           
    END

更新程序

ALTER PROCEDURE [dbo].[UserReportData] 
                @As_ONDATE Datetime 

                AS 
            BEGIN 
                    DECLARE @REPORTDATE datetime        
                    DECLARE @USERNAME varchar(110)      

            Select * INTO #temptable
        FROM
                    (
                        select  a.CUser_id, b.User_Id, a.U_datetime
                        as REPORTDATE, ISNULL(b.first_Name, '') + ' ' + ISNULL(b.last_name, '') AS USERNAME                         
                        from inward_doc_tracking_trl a inner join user_mst b
                        on a.CUser_id = b.mkey
                        and a.U_datetime >= @As_ONDATE
                ) as x

DECLARE Cur_1 CURSOR
            FOR SELECT CUser_id, User_Id FROM #temptable

                    OPEN Cur_1
                        DECLARE @CUser_id INT
                        DECLARE @User_Id INT
                        --DECLARE @USERNAME VARCHAR (100)
                        FETCH NEXT FROM Cur_1 
                        INTO @CUser_id, @User_Id

                        WHILE (@@FETCH_STATUS = 0)
            BEGIN

                            SELECT @REPORTDATE = U_datetime FROM inward_doc_tracking_trl                        
                            where  U_datetime >= @As_ONDATE 

                            SELECT @USERNAME = ISNULL(b.first_Name, '') + ' ' + ISNULL(b.last_name, '') 
                                FROM inward_doc_tracking_trl a 
                                INNER JOIN user_mst b on a.CUser_id = b.mkey 
                                where a.U_datetime >= @As_ONDATE                            

                            UPDATE #temptable
                                SET REPORTDATE = @REPORTDATE,
                                    USERNAME = @USERNAME
                                WHERE CUser_id = @CUser_id
                                AND User_Id = @User_Id  


                FETCH NEXT FROM Cur_1 INTO @CUser_id, @User_Id
                    END
            CLOSE Cur_1
            DEALLOCATE Cur_1


            SELECT * FROM #temptable
                        DROP TABLE #temptable                           
    END

【问题讨论】:

  • 您没有将 ant 值设置为 @USERNAME
  • @Arulkumar:是的,但是如何设置它
  • 和其他游标变量一样
  • @Arulkumar:在设置值时我收到错误Incorrect syntax near 'USERNAME'. 这是我尝试过的SELECT @USERNAME = b.first_Name + ' ' + b.last_name USERNAME from inward_doc_tracking_trl a inner join user_mst b on a.CUser_id = b.mkey and a.U_datetime >= @As_ONDATE
  • @IvanStarostin:我像上面一样尝试过,但得到错误Incorrect syntax near 'USERNAME'.

标签: sql sql-server stored-procedures sql-server-2005


【解决方案1】:

首先在初始BEGIN 块中注释@USERNAME 声明

 -- DECLARE @USERNAME varchar(110)

然后处理USERNAMENULL 值,就像在SELECT * INTO 块中一样

 ISNULL(b.first_Name, '') + ' ' + ISNULL(b.last_name, '') AS USERNAME

然后在CURSOR中添加@USERNAME

DECLARE Cur_1 CURSOR
        FOR SELECT CUser_id, User_Id, USERNAME FROM #temptable

            OPEN Cur_1
                    DECLARE @CUser_id INT
                    DECLARE @User_Id INT
                    DECLARE @USERNAME VARCHAR (200) -- can set your required length
                    FETCH NEXT FROM Cur_1 
                    INTO @CUser_id, @User_Id

那么@USERNAME 就不会抛出NULL 错误


更新:根据您的 cmets,我更新了答案:

所以你想根据U_datetime >= @As_ONDATE 条件获得@USERNAME

因此,使用您现有的代码并在 CURSOR 内再添加一个块,以便在 SELECT @REPORTDATE = U_datetime FROM inward_doc_tracking_trl where U_datetime >= @As_ONDATE 之后获取 @USERNAME

SELECT @USERNAME = ISNULL(b.first_Name, '') + ' ' + ISNULL(b.last_name, '') -- no need of column alias here
FROM inward_doc_tracking_trl a 
INNER JOIN user_mst b on a.CUser_id = b.mkey 
WHERE a.U_datetime >= @As_ONDATE

【讨论】:

  • 请查看UPDATE答案
  • 是的,它可以正常工作。但所有行都来自相同的 USERNAME。
  • 您能否在问题中发布您最近的代码。更新coe后可能是笔误。
  • 更新的代码是正确的,您对所有@USERNAME 使用相同的条件,所以显然所有这些都具有相同的值,如果您想根据您的CUser_id 获取@USERNAME,User_id 添加WHERE 子句中的那些值,例如 WHERE a.U_datetime >= @As_ONDATE AND a.CUser_id = @CUser_id AND b.User_id = @User_id
【解决方案2】:

也许试试这个:

ALTER PROCEDURE [dbo].[UserReportData] 
@As_ONDATE Datetime 

AS 
BEGIN 
    Select * INTO #temptable
    FROM
    (
        select  
            a.CUser_id, 
            b.User_Id, 
            a.U_datetime as REPORTDATE, 
            ISNULL( b.first_Name + ' '  + b.last_name, 'NONAME' ) as USERNAME -- normally if one of the two is null then all of it is Null
        from inward_doc_tracking_trl a inner join user_mst b
        on a.CUser_id = b.mkey
        and a.U_datetime >= @As_ONDATE
    ) as x



    DECLARE @REPORTDATE datetime 

    -- moved out of the loop
    SELECT @REPORTDATE = U_datetime 
    FROM inward_doc_tracking_trl                        
    where  U_datetime >= @As_ONDATE -- this might bring more than one rows I think ???????


    DECLARE Cur_1 CURSOR FOR SELECT CUser_id, User_Id, USERNAME FROM #temptable
    DECLARE @CUser_id INT
    DECLARE @User_Id INT    
    DECLARE @USERNAME varchar(110) 

    OPEN Cur_1    
    FETCH NEXT FROM Cur_1 INTO @CUser_id, @User_Id, @USERNAME

    WHILE (@@FETCH_STATUS = 0)
    BEGIN

        UPDATE #temptable SET 
            REPORTDATE = @REPORTDATE,
            USERNAME =  @USERNAME
        WHERE 
            CUser_id = @CUser_id
            AND User_Id = @User_Id  

        FETCH NEXT FROM Cur_1 INTO @CUser_id, @User_Id, @USERNAME

    END

    CLOSE Cur_1
    DEALLOCATE Cur_1

    SELECT * FROM #temptable
    DROP TABLE #temptable                           
END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多