3

我有一个这样的 SQL Server 查询:

CREATE TABLE ##Temp(
    OrderID NVARCHAR(100), 
    ID INT,
    Prices INT,
    Total INT
);

INSERT INTO ##Temp (ID, Prices, OrderID, Total)
SELECT  fc.ID, f.Prices, f.OrderID, 
        (SUM(f.Prices) OVER()) AS Total 
FROM FruitCrates fc
LEFT JOIN Fruits f ON fc.ID = f.FruitCrateID
WHERE  fc.OrderID LIKE '18_1635' 
  AND fc.Rights = 1 
  AND fc.Cancelled = 0 
  AND f.OrderID IS NOT NULL;

SELECT * FROM ##Temp;

但我不断收到错误消息:

消息 207,级别 16,状态 1,第 12 行
无效的列名称“总计”。

我认为这是因为我没有OVER()正确使用我不知道如何修复它。

请注意

SELECT声明在没有放在之后就起作用INSERT

没有 INSERT 的结果

╔═════╦════════╦══════════╦═══════╗
║ ID  ║ Prices ║ OrderID  ║ Total ║
╠═════╬════════╬══════════╬═══════╣
║  77 ║      1 ║ 1_370    ║   104 ║
║  19 ║    101 ║ 1811_171 ║   104 ║
║  77 ║      2 ║ 1811_171 ║   104 ║
╚═════╩════════╩══════════╩═══════╝   
4

1 回答 1

1

带有插入的错误消息Invalid column name 'Total'.清楚地表明表具有与语句中##Temp的列列表不同的架构。INSERT INTO (...)

要对其进行故障排除,您应该始终在插入之前检查元数据(列名):

SELECT *
FROM ##Temp
WHERE 1=2;

然后你可以很容易地发现它与你假设的不同。

现在您正在使用全局临时表,只要最后一个引用它的连接处于活动状态,它就会一直存在。您应该考虑使用本地临时表。

要解决您的问题,您可以:

  1. 使用不同的名称以避免冲突
  2. 就在您可以之前(如果未在嵌套过程中使用):

    如果 OBJECT_ID('tempdb..##temp') 不为空     
    删除表##temp
    
    创建表##temp...
    

当存储过程调用另一个存储过程并且两者(外部和内部)都创建具有相同名称的临时表时,还有一个令人讨厌的情况。你应该避免它。

CREATE PROCEDURE #outer
AS
BEGIN
   CREATE TABLE ##temp (id INT, guid UNIQUEIDENTIFIER, col2 VARCHAR(100));
   INSERT INTO ##temp VALUES(1,NEWID(), 'a');
   SELECT * FROM ##temp;
   EXEC [#inner];
END
GO

CREATE PROCEDURE #inner
AS
BEGIN
    CREATE TABLE ##temp (id INT, total INT);  -- no error during creation

    INSERT INTO ##temp(id, total)
    SELECT 2, 10;

    SELECT * FROM ##temp;
END
GO

EXEC #outer
-- Invalid column name 'total'.

LiveDemo

最有趣的是,当您使用具有相同列数(或默认值)的本地临时表并且可以进行隐式转换时,它将通过:

CREATE PROCEDURE #outer
AS
BEGIN
CREATE TABLE #temp (id INT, col2 varchar(10));
   INSERT INTO #temp VALUES(1, 'a');
   SELECT * FROM #temp;
   EXEC [#inner];
END
GO

CREATE PROCEDURE #inner
AS
BEGIN
    CREATE TABLE #temp (id INT, total INT);
    INSERT INTO #temp
    SELECT 2, 10;

    SELECT * FROM #temp;
END
GO

EXEC #outer

LiveDemo2

以及类型不兼容的示例:

CREATE PROCEDURE #outer
AS
BEGIN
CREATE TABLE #temp (id INT, col2 UNIQUEIDENTIFIER);
INSERT INTO #temp VALUES(1, NEWID());
   SELECT * FROM #temp;
   EXEC [#inner];
END
GO

CREATE PROCEDURE #inner
AS
BEGIN
    CREATE TABLE #temp (id INT, total INT);
    INSERT INTO #temp
    SELECT 2, 10;

    SELECT * FROM #temp;
END
GO

EXEC #outer

操作数类型冲突:int 与 uniqueidentifier 不兼容

于 2016-01-14T12:03:03.167 回答