关于INTO关键字的错误消息

时间:2018-07-26 12:41:40

标签: sql sql-server sql-server-2014

有人知道为什么INTO关键字在下面的第一种方法中有效,但在第二种方法中无效吗?

在本视频的前5分钟中,我得到了两种有关创建临时表的方法:https://www.youtube.com/watch?v=3ZtYrELHP8M

方法1

SELECT 
    CAST (date AS DATE) AS #DateWk  
INTO
    #DateWk  
FROM
    AggregatedSalesHistory
WHERE 
    date >= '1-2-2014' 

SELECT * FROM #DateWk

尝试方法2时,出现以下错误消息:

  

关键字“ INTO”附近的语法不正确。

这是方法2的代码:

CREATE TABLE #DateWeek
(   
    Title VARCHAR(MAX),
    ReleaseDate DATETIME
)

INSERT INTO #DateWk
    SELECT 
        CAST (date AS DATE) AS #DateWk,  
    INTO #DateWk  
    FROM AggregatedSalesHistory
    WHERE date >= '1-2-2014' 

SELECT * FROM #DateWk

3 个答案:

答案 0 :(得分:5)

如果表已经存在,则不能再使用SELECT .... INTO ....-您需要使用:

INSERT INTO #DateWk
    SELECT CAST (date AS DATE)   
    FROM AggregatedSalesHistory
    WHERE date >= '1-2-2014' 

您已经在开始时指定了INSERT INTO-不要不要INTO ..之后添加SELECT,然后就可以正常工作了。 / p>

如果你这样做

SELECT (list of columns)
INTO SomeTable
FROM ....
WHERE..... 

然后,此SELECT将自动创建SomeTable表-但是如果SomeTable已经存在,则此代码将失败-在这种情况下,请使用:

INSERT INTO SomeTable(list-of-columns)
    SELECT (list of columns)
    FROM ....
    WHERE..... 

更新:通常,总是明确指定要插入的列是一个好习惯-避免出现类似现在的问题。

因此将您的声明更改为:

INSERT INTO #DateW (ReleaseDate)
    SELECT CAST (date AS DATE) 
    FROM AggregatedSalesHistory  
    WHERE date >= '1-2-2014' 

如果您INSERT语句中指定表名之后的列列表,则必须为表的 all 列提供值-按照它们在表格中出现的顺序。

答案 1 :(得分:0)

如果要与method1比较,这不是有效的语法:

INSERT INTO #DateWk
SELECT 
    CAST (date as Date) as #DateWk,  
    INTO #DateWk  
FROM AggregatedSalesHistory
WHERE date >= '1-2-2014' 

无论何时做:

SELECT CAST (date as Date) as #DateWk INTO #DateWk  
FROM AggregatedSalesHistory

这将自动创建#DateWk表并同时插入数据。因此,SQL Server将不会编译作为方法组合的第二个方法,否则将引发错误。

所以,第二种方法是:

INSERT INTO #DateWk (ReleaseDate)
    SELECT CAST (date AS DATE) 
    FROM AggregatedSalesHistory
    WHERE date >= '1-2-2014' 

SELECT * FROM #DateWk

答案 2 :(得分:0)

您的示例确实演示了填充临时表的两种不同方法,尽管正如您所说,第二种方法包含语法错误。

方法1是一种创建表的“简单而肮脏的”方法。当您发出SELECT...INTO语句时,SQL引擎会在后台编写它自己的CREATE TABLE语句。它使用SELECT查询的结果对数据类型做出最佳猜测,然后填充表。如果您在此查询中指定的临时表已经存在,则该语句将引发错误,如果该表存在,则运行CREATE TABLE语句的方式将失败。

值得注意的是,在您的示例中,为您自动生成的第一个表将具有一个称为#DateWk的列。列名开头的#有点奇怪,但这是您的数据。随便叫什么。

在方法2中,您将明确控制CREATE TABLE语句。即使您愿意,也可以决定列名称,数据类型,索引。然后,就像使用永久表一样,您可以发出INSERT INTO语句来填充它。您可能正在使用插入的最常见形式INSERT INTO...SELECT...FROM...

您收到的错误来自第二个INTO子句,因为如上所述和其他人所述,您要插入的表已经存在。即使清除了该内容,查询也将再次失败。下次,它将引发此错误:

  

列名或提供的值数与表定义不匹配。

这是因为您创建的临时表有两列,但是您只插入日期字段。您可以这样做,但必须指定要填充的列,以便SQL知道将数据放置在何处。

这将起作用,

CREATE TABLE #AggregatedSalesHistory 
(
  [date] VARCHAR(10)
);


INSERT #AggregatedSalesHistory
  (
    date
  )
VALUES
  (
    '2018-07-26' -- date - varchar(10)
  )


CREATE TABLE #DateWk
(   
    Title VARCHAR(MAX),
    ReleaseDate DATETIME
);

INSERT INTO #DateWk (ReleaseDate)
    SELECT 
        CAST (date AS DATE) AS #DateWk --You had a comma here. It'd throw a syntax error.
    FROM #AggregatedSalesHistory
    WHERE date >= '1-2-2014' 

SELECT * FROM #DateWk

--Results
+-------+-------------------------+
| Title |       ReleaseDate       |
+-------+-------------------------+
| NULL  | 2018-07-26 00:00:00.000 |
+-------+-------------------------+