我试图使用另一个表的输入将数据插入到表中。尽管这对于许多数据库引擎来说是完全可行的,但我似乎总是很难记住当前SQL引擎(MySQL、Oracle、SQL Server、Informix和DB2)的正确语法。

是否有来自SQL标准(例如SQL-92)的银弹语法允许我插入值而不必担心底层数据库?


当前回答

select *
into tmp
from orders

看起来不错,但只有当tmp不存在时才有效(创建并填充)。(SQL服务器)

要插入现有tmp表:

set identity_insert tmp on

insert tmp 
([OrderID]
      ,[CustomerID]
      ,[EmployeeID]
      ,[OrderDate]
      ,[RequiredDate]
      ,[ShippedDate]
      ,[ShipVia]
      ,[Freight]
      ,[ShipName]
      ,[ShipAddress]
      ,[ShipCity]
      ,[ShipRegion]
      ,[ShipPostalCode]
      ,[ShipCountry] )
      select * from orders

set identity_insert tmp off

其他回答

要在第一个答案中添加一些内容,当我们只需要另一个表中的几个记录时(在本例中只有一个):

INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4) 
VALUES (value1, value2, 
(SELECT COLUMN_TABLE2 
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);

我看到的两个答案在Informix中都很好,基本上都是标准的SQL。即表示法:

INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;

Informix和所有DBMS都可以很好地工作。(在5年或更多年前,这是MySQL并不总是支持的类型;现在它对这种标准SQL语法有了良好的支持,而且,AFAIK,它在这种表示法上可以正常工作。)列列表是可选的,但按顺序指示目标列,因此SELECT结果的第一列将进入第一列,在没有列列表的情况下,SELECT结果的第一列进入目标表的第一列。

系统之间的不同之处在于用于标识不同数据库中的表的符号——该标准对数据库间(更不用说DBMS间)操作没有任何意义。使用Informix,可以使用以下符号来标识表:

[dbase[@server]:][owner.]table

也就是说,您可以指定一个数据库,如果该数据库不在当前服务器中,则可以选择标识托管该数据库的服务器,然后是可选的所有者、点,最后是实际的表名。SQL标准使用Informix称为所有者的术语模式。因此,在Informix中,以下任何符号都可以标识表:

table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table

一般情况下,不需要对所有者进行报价;但是,如果使用引号,则需要正确拼写所有者名称,因为它区分大小写。即:

someone.table
"someone".table
SOMEONE.table

它们都标识相同的表。对于Informix,MODE ANSI数据库有一个轻微的复杂性,其中所有者名称通常转换为大写(Informix是例外)。也就是说,在MODE ANSI数据库(不常用)中,可以编写:

CREATE TABLE someone.table ( ... )

系统目录中的所有者名称将是“SOMEONE”,而不是“SOMEONE”。如果将所有者名称括在双引号中,则其作用类似于分隔标识符。对于标准SQL,分隔标识符可以在许多地方使用。使用Informix,您只能在所有者名称周围使用它们——在其他上下文中,Informix将单引号和双引号字符串都视为字符串,而不是将单引号字符串分隔为字符串,将双引号字符串分隔成分隔标识符。(当然,为了完整起见,有一个环境变量DELIMIDENT,可以设置为任何值,但Y是最安全的,它表示双引号始终围绕分隔标识符,单引号始终围绕字符串。)

请注意,MS SQL Server设法使用方括号中的[分隔标识符]。我觉得这很奇怪,而且肯定不是SQL标准的一部分。

这对我有用:

insert into table1 select * from table2

这句话和甲骨文的有点不同。

对于Microsoft SQL Server,我建议您学习解释MSDN上提供的语法。使用谷歌,查找语法比以往任何时候都容易。

对于这种特殊情况,请尝试

谷歌:插入网址:microsoft.com

第一个结果是http://msdn.microsoft.com/en-us/library/ms174335.aspx

如果您发现难以解释页面顶部给出的语法,请向下滚动到示例(“使用SELECT和EXECUTE选项从其他表插入数据”)。

[ WITH <common_table_expression> [ ,...n ] ]
INSERT 
{
        [ TOP ( expression ) [ PERCENT ] ] 
        [ INTO ] 
        { <object> | rowset_function_limited 
          [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
        }
    {
        [ ( column_list ) ] 
        [ <OUTPUT Clause> ]
        { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n     ] 
        | derived_table       <<<<------- Look here ------------------------
        | execute_statement   <<<<------- Look here ------------------------
        | <dml_table_source>  <<<<------- Look here ------------------------
        | DEFAULT VALUES 
        }
    }
}
[;]

这应该适用于那里可用的任何其他RDBMS。记住所有产品IMO的所有语法是没有意义的。

如果您想在表中插入一些数据而不想写入列名。

INSERT INTO CUSTOMER_INFO
   (SELECT CUSTOMER_NAME,
           MOBILE_NO,
           ADDRESS
      FROM OWNER_INFO cm)

其中表格如下:

            CUSTOMER_INFO               ||            OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS     || CUSTOMER_NAME | MOBILE_NO | ADDRESS 
--------------|-----------|---------    || --------------|-----------|--------- 
      A       |     +1    |   DC        ||       B       |     +55   |   RR  

结果:

            CUSTOMER_INFO               ||            OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS     || CUSTOMER_NAME | MOBILE_NO | ADDRESS 
--------------|-----------|---------    || --------------|-----------|--------- 
      A       |     +1    |   DC        ||       B       |     +55   |   RR
      B       |     +55   |   RR        ||