SELECT * INTO FAILS

时间:2015-08-04 10:19:21

标签: sql tsql sql-server-2008-r2

我有以下表结构:

CREATE TABLE [dbo].[UTS_USERCLIENT_MAPPING_USER_LIST]
(
    [MAPPING_ID] [int] IDENTITY(1,1) NOT NULL,
    [USER_ID] [varchar](50) NULL,
    [USER_EMAIL_ID] [varchar](100) NULL,
    [USER_CREATED_DATE] [datetime] NULL,
    [USER_IS_ACTIVE] [bit] NULL,

    CONSTRAINT [PK_UTS_USERCLIENT_MAPPING_USER_LIST] 
       PRIMARY KEY CLUSTERED ([MAPPING_ID] ASC)
       WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
             IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
             ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

在存储过程中,我有这段代码:

ALTER PROCEDURE [dbo].[PROC_UTS_USER_CLIENTMAPPING_LIST_SET] 
    (@RETURN_CODE INT OUTPUT,
     @RETURN_MESSAGE NVARCHAR(512) OUTPUT,
     @XML_USER_LIST xml)
AS
BEGIN TRY
    SELECT
        ROW_NUMBER() OVER(ORDER BY x.value('USERNAME[1]','nvarchar(50)')) AS MAPPING_ID,
        x.value('USERNAME[1]', 'nvarchar(50)') as USER_ID,
        x.value('EMAILID[1]', 'nvarchar(50)') as USER_EMAIL_ID,
        x.value('CREATEDDATE[1]', 'datetime') as USER_CREATED_DATE,
        x.value('ISACTIVE[1]', 'bit') as USER_IS_ACTIVE 
    INTO #tempXML
    FROM @XML_USER_LIST.nodes('/DocumentElement/dtLstUsers') AS TEMPTABLE(x)

    SELECT * 
    INTO UTS_USERCLIENT_MAPPING_USER_LIST 
    FROM #tempXML
END TRY

我的问题是上面的存储过程没有将数据插入UTS_USERCLIENT_MAPPING_USER_LIST表的#tempXML

我确保#tempXML表包含值。

enter image description here

6 个答案:

答案 0 :(得分:3)

您的查询中存在一些缺陷:

1 - 您试图在插入表格之前插入IDENTITY值而不设置IDENTITY_INSERT,然后将其设置为OFF

glutMainLoop

2 - SELECT * INTO表将假设该表不存在并将尝试在那里创建它,将失败 - >需要使用INSERT INTO SELECT

SET IDENTITY_INSERT UTS_USERCLIENT_MAPPING_USER_LIST ON 

3 - 您正在使用ROW_NUMBER函数计算MAPPING_ID,该函数将从1开始到n(其中n是您在xml中拥有的节点数),但是您的表在MAPPING_ID列上有一个PRIMARY KEY,这意味着UNIQUE所以第二次要插入MAPPING_ID 1时,它将失败。

4 - 如果您的CATCH块为空,则会隐藏您的错误

现在,没有真正理解您对MAPPING_ID列的需求的解决方案是将insert语句更改为:

INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST (cols)
SELECT cols
FROM  #temp

如果你有一个从xml中找到的有效MAPPING_ID,那么:

INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST ([USER_ID], [USER_EMAIL_ID], [USER_CREATED_DATE], [USER_IS_ACTIVE])
SELECT  [USER_ID], [USER_EMAIL_ID], [USER_CREATED_DATE], [USER_IS_ACTIVE]
FROM    #tempXML

答案 1 :(得分:2)

根据我的理解,您需要提及除Mapping_ID之外的所有列名称。见下面的代码

INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST (
        USER_ID,
        USER_EMAIL_ID,
        USER_CREATED_DATE,
        USER_IS_ACTIVE)
select  USER_ID,
        USER_EMAIL_ID,
        USER_CREATED_DATE,
        USER_IS_ACTIVE
 from #tempXML

答案 2 :(得分:1)

看起来你需要像Sparky建议的那样打开IDENTITY_INSERT。

答案 3 :(得分:1)

另一种可能的解决方案是您根本不使用IDENTITY列 - 如果不需要它。 (如果此表仅从此存储过程获取数据,则无需使用IDENTITY列):

CREATE TABLE [dbo].[UTS_USERCLIENT_MAPPING_USER_LIST](
    [MAPPING_ID] [int] NOT NULL,
    [USER_ID] [varchar](50) NULL,
    [USER_EMAIL_ID] [varchar](100) NULL,
    [USER_CREATED_DATE] [datetime] NULL,
    [USER_IS_ACTIVE] [bit] NULL,

CONSTRAINT [PK_UTS_USERCLIENT_MAPPING_USER_LIST] PRIMARY KEY CLUSTERED 
(
    [MAPPING_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

答案 4 :(得分:1)

真正的问题是,

SELECT * INTO总是创建新表。

所以我需要在创建之前删除现有的表。

当我:

DROP TABLE UTS_USERCLIENT_MAPPING_USER_LIST 

 SELECT * 
    INTO UTS_USERCLIENT_MAPPING_USER_LIST 
    FROM #tempXML

然后它奏效了。

谢谢。

答案 5 :(得分:1)

难道你不能完全跳过临时表吗?

-- TRUNCATE TABLE HERE, IF NEED BE

INSERT INTO UTS_USERCLIENT_MAPPING_USER_LIST (<ColumnList>)
SELECT
    ROW_NUMBER() OVER(ORDER BY x.value('USERNAME[1]','nvarchar(50)')) AS MAPPING_ID,
    x.value('USERNAME[1]', 'nvarchar(50)') as USER_ID,
    x.value('EMAILID[1]', 'nvarchar(50)') as USER_EMAIL_ID,
    x.value('CREATEDDATE[1]', 'datetime') as USER_CREATED_DATE,
    x.value('ISACTIVE[1]', 'bit') as USER_IS_ACTIVE 
FROM @XML_USER_LIST.nodes('/DocumentElement/dtLstUsers') AS TEMPTABLE(x)