【问题标题】:OUPUT for insert from table variable gives: "The multi-part identifier "k.CustomerName" could not be bound."从表变量中插入的输出给出:“无法绑定多部分标识符“c.CustomerName”。”
【发布时间】:2011-12-20 04:41:24
【问题描述】:

我在这里看到很多人在堆栈溢出时出现此错误消息,并且都在另一种情况下得到它。在已经存在的问题中,我找不到自己的情况。所以我希望有人可以帮助我解决这个问题。我使用 SQL server 9 和 SQL management studio 10。

--import the customers.
CREATE TABLE #AllCustomers(CustomerName NVARCHAR(100), CustomerNr NVARCHAR(16));
BULK INSERT #AllCustomers
FROM 'C:\allcustomers.txt' 
WITH 
( 
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
);

DECLARE @DefinitionId int;

--get the id of the definition for which I have to set values.
SELECT @DefinitionId = pkDefinitionId
FROM dbo.Definitions
WHERE Name = 'DEFINITION-OF-MY-ITEM';

DECLARE @TempA TABLE (CustomerName NVARCHAR(255), CustomerNr NVARCHAR(16));

--reduce the set of all customers to only the customer for whom I have to insert.
WITH MyView AS 
    (SELECT kciv.CustomerNr
     FROM dbo.CustomerItems kciv
     INNER JOIN dbo.DefinitionToItem civ ON civ.pkDefinitionToItemId = kciv.pkCustomerItemId
     WHERE civ.fkDefinitionId = @DefinitionId)
INSERT INTO @TempA 
SELECT k.CustomerName , k.CustomerNr 
FROM #AllCustomers k
WHERE k.CustomerNr NOT IN (SELECT CustomerNr FROM MyView);

--used to store the generated primairy keys I need for creating relations.
DECLARE @ItemIds TABLE (CustomerName NVARCHAR(255), CustomerNr NVARCHAR(16), pkItemId int);
DECLARE @DefinitionToItemIds TABLE (CustomerName NVARCHAR(255), CustomerNr NVARCHAR(16), pkDefinitionToItemId int);

--insert the default values.
INSERT INTO dbo.Items
OUTPUT k.CustomerName, k.CustomerNr, inserted.pkItemId 
  INTO @ItemIds (CustomerName, CustomerNr, pkGenericValueId)
SELECT 2, 1, null, null, 1, null
FROM @TempA k;

--couple the values to the definition.
INSERT INTO dbo.DefinitionToItem
OUTPUT gvd.CustomerName, gvd.CustomerNr, inserted.pkDefinitionToItemId 
  INTO @DefinitionToItemIds
SELECT 1, 0, @DefinitionId, gvd.pkItemId
FROM @ItemIds gvd;

--couple the 'coupling' to the customers.
INSERT INTO dbo.CustomerItems
SELECT civd.pkDefinitionToItemId, civd.CustomerName, civd.CustomerNr
FROM @DefinitionToItemIds civd;

我在运行查询时遇到四个错误,都在代码示例末尾附近的两个输出行上。

消息 4104,级别 16,状态 1,行 64 无法绑定多部分标识符“k.CustomerName”。
消息 4104,第 16 级,状态 1,第 64 行 无法绑定多部分标识符“k.CustomerNr”。
消息 4104,第 16 级,状态 1,第 69 行 无法绑定多部分标识符“gvd.CustomerName”。
消息 4104,第 16 级,状态 1,第 69 行 无法绑定多部分标识符“gvd.CustomerNr”。

我检查了拼写错误,但没有找到(我可能在此处介绍了一些拼写错误,但同时更改了一些名称以删除上下文)。我不知道为什么会出错。我看过MSDN,但我找不到任何问题。

额外信息:

数据库架构如下:

  • Items 表包含“值”(pkItemId,一堆其他列)
  • 定义表包含“定义”(pkDefinitionId、名称、一堆其他列)
  • DefinitionToItem 表将值与定义相匹配(pkDefinitionToItemId、fkDefinitionId、fkItemId)
  • CustomerItems 表将客户链接到 DefinitionToItemId(pkDefinitionToItemId、CustomerName、CustomerNr)。

我需要实现的是将默认值(即“2、1、null、null、1、null”链接到 definitino 'DEFINITION-OF-MY-ITEM')插入到给定集合的项目数据库中顾客。有些人可能已经有了该定义的值,然后我应该跳过它们(因此是@TempA)。 所以我将值插入到 Items 中,然后在 DefinitionToItem 中插入定义和项目之间的耦合,最后通过插入到 DefinitionToItem 表中将客户耦合到 DefinitionToItem。

如果有比我正在做的更好的方法来实现这一点,那么我愿意接受建议。

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql


    【解决方案1】:

    我认为您采用的方法使情况复杂化。

    首先,OUTPUT 子句不会按照您需要的方式工作,因为您只能使用插入的列,并且您想使用源表中的列,但要使用未插入的列。 (以客户名为例)。

    我建议你有两种方法可以解决这个问题:

    1. 第一种方法。改变你的查询。使用 OUTPUT,但输出一个 id 字段。然后,在您第一次插入 ITEMS 后,将新表与源表连接起来。现在您将可以访问所有字段,并且仍然可以确定应该插入哪些记录。

    2. 第二种方法。放下你的临时表。使用带有 WHERE _ NOT IN 子句的简单插入语句。这消除了复杂性,仍然实现了不插入重复的目标,只是在更接近的水平上。

    【讨论】:

    • 问题是,如何在不获取每个客户编号的每个 id 的情况下将 id 与客户编号连接起来?
    • Items 表中的一个项目可以链接到多个客户吗?如果没有,您的数据库结构可以通过将 customerID 添加到 Items 表来解决此问题。如果不是这种情况,您将不得不考虑使用与项目表具有相同种子的临时表,您可以在其中添加客户 ID 列。这将使您能够仅在会话中保持客户和项目之间的链接,并且您可以使用该表作为基础插入到所有其他表中。
    【解决方案2】:

    用途:

    INSERT INTO dbo.Items
    OUTPUT INSERTED.CustomerName, INSERTED.CustomerNr, INSERTED.pkItemId 
      INTO @ItemIds (CustomerName, CustomerNr, pkGenericValueId)
    SELECT 2, 1, null, null, 1, null
      FROM @TempA k;
    
    INSERT INTO dbo.DefinitionToItem
    OUTPUT INSERTED.CustomerName, INSERTED.CustomerNr, INSERTED.pkDefinitionToItemId 
      INTO @DefinitionToItemIds
    SELECT 1, 0, @DefinitionId, gvd.pkItemId
      FROM @ItemIds gvd;
    

    您可能需要更改列名,因为它们需要来自被插入的表,而不是它们来源的列。

    【讨论】:

    • 它没有用。我需要为每个客户插入这些值,并且需要@ItemsIds 为每个客户包含我插入的值的 id。但客户名称和编号不应进入ItemsDefinitionToItem 表中。
    • @MatthijsWessels - 您无法使用 output 获取未插入目标表的值。如果您要使用 SQL Server 2008,您可以在可能的情况下使用合并。 stackoverflow.com/questions/5365629/…
    【解决方案3】:

    您的表 #AllCustomers 在此查询中不包含字段 CustomerName

    SELECT k.CustomerName , k.CustomerNr 
    FROM #AllCustomers k
    

    【讨论】:

    • 你说得对,我会改正的。但我仍然得到同样的错误
    • 给子查询添加列别名 SELECT 2, 1, null, null, 1, null FROM @TempA k;
    • 我把它改成了:2 AS VALUETYPE, 1 AS Version, null AS IValue, null AS SValue, 1 AS BValue, null AS DValue,但没有运气
    • 对于错误信息,您不能使用表别名,除了“inserted”或“deleted”用于 INSERT 语句中使用的 OUTPUT 子句
    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    • 2011-11-10
    • 2010-11-02
    相关资源
    最近更新 更多