插入...值(SELECT ... FROM ...)
我正在尝试使用另一个表的输入INSERT INTO
一个表。 尽管这对于许多数据库引擎来说是完全可行的,但我似乎总是很难记住当今 SQL
引擎的正确语法(MySQL,Oracle,SQL Server,Informix 和 DB2)。
是否有来自 SQL 标准的银弹语法(例如 SQL-92 )这将允许我插入值而不用担心底层数据库?
I am trying to INSERT INTO
a table using the input from another table. Although this is entirely feasible for many database engines, I always seem to struggle to remember the correct syntax for the SQL
engine of the day (MySQL, Oracle, SQL Server, Informix, and DB2).
Is there a silver-bullet syntax coming from an SQL standard (for example, SQL-92) that would allow me to insert the values without worrying about the underlying database?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(27)
Postgres 支持以下功能:
创建表company.monitor2作为select * from company.monitor;
Postgres supports next:
create table company.monitor2 as select * from company.monitor;
如果你首先创建表,你可以这样使用;
这会插入值,但与创建新的复制表不同。
If you create table firstly you can use like this;
This metot insert values but differently with creating new copy table.
在 informix 中,它的工作方式正如 Claude 所说:
In informix it works as Claude said:
如果您使用 INSERT VALUES 路径插入多行,请确保使用括号将 VALUES 分隔到集合中,这样:
否则 MySQL 会认为“列计数与第 1 行的值计数不匹配”,并且您最终会编写一个简单的代码当您最终弄清楚该怎么做时,请发布。
If you go the INSERT VALUES route to insert multiple rows, make sure to delimit the VALUES into sets using parentheses, so:
Otherwise MySQL objects that "Column count doesn't match value count at row 1", and you end up writing a trivial post when you finally figure out what to do about it.
这是使用多个表获取源的另一个示例:
Here is another example where source is taken using more than one table:
以下是从多个表插入的方法。 在这个特定的例子中,您在多对多场景中拥有一个映射表:(
我意识到匹配学生姓名可能会返回多个值,但您明白了。当 ID 为身份列并且未知。)
Here's how to insert from multiple tables. This particular example is where you have a mapping table in a many to many scenario:
(I realise matching on the student name might return more than one value but you get the idea. Matching on something other than an Id is necessary when the Id is an Identity column and is unknown.)
如果您想使用 SELECT * INTO 表插入所有列,您可以尝试此操作。
You could try this if you want to insert all column using
SELECT * INTO
table.实际上我更喜欢 SQL Server 2008 中的以下功能:
它消除了添加 Insert() 集的步骤,您只需选择将哪些值放入表中即可。
I actually prefer the following in SQL Server 2008:
It eliminates the step of adding the Insert () set, and you just select which values go in the table.
这对我有用:
这句话与 Oracle 的有点不同。
This worked for me:
The sentence is a bit different from Oracle's.
这适用于所有 DBMS
This works on all DBMS
对于 Microsoft SQL Server,我建议学习解释 MSDN 上提供的语法。 有了 Google,查找语法比以往任何时候都容易。
对于这种特殊情况,请尝试
第一个结果将是 http://msdn。 microsoft.com/en-us/library/ms174335.aspx
如果您发现很难解释给出的语法,请向下滚动到 示例(“使用 SELECT 和 EXECUTE 选项从其他表插入数据”)页面顶部。
这应该适用于任何其他可用的 RDBMS。 在我看来,记住所有产品的所有语法是没有意义的。
For Microsoft SQL Server, I will recommend learning to interpret the SYNTAX provided on MSDN. With Google it's easier than ever, to look for syntax.
For this particular case, try
The first result will be http://msdn.microsoft.com/en-us/library/ms174335.aspx
scroll down to the example ("Using the SELECT and EXECUTE options to insert data from other tables") if you find it difficult to interpret the syntax given at the top of the page.
This should be applicable for any other RDBMS available there. There is no point in remembering all the syntax for all products IMO.
从任何其他表插入多条记录的最佳方法。
Best way to insert multiple records from any other tables.
看起来不错,但仅当 tmp 不存在时才有效(创建它并填充)。 (SQL 服务器)
插入现有的 tmp 表:
Looks nice, but works only if tmp doesn't exists (creates it and fills). (SQL sever)
To insert into existing tmp table:
如果你想向表中插入一些数据而不想写列名。
表格所在位置:
结果:
IF you want to insert some data into a table without want to write column name.
Where the tables are:
Result:
如果您要为
SELECT
部分中的所有列提供值,则无需在INSERT INTO
部分中指定列即可完成此操作。假设 table1 有两列。 此查询应该有效:
这不起作用(未指定
col2
的值):我正在使用 MS SQL Server。 我不知道其他 RDMS 是如何工作的。
This can be done without specifying the columns in the
INSERT INTO
part if you are supplying values for all columns in theSELECT
part.Let's say table1 has two columns. This query should work:
This WOULD NOT work (value for
col2
is not specified):I'm using MS SQL Server. I don't know how other RDMS work.
只需在 INSERT 中使用括号将 SELECT 子句插入即可。 例如这样:
Just use parenthesis for SELECT clause into INSERT. For example like this :
这是使用带有 select 的值的另一个示例:
This is another example using values with select:
已知表列顺序时的简单插入:
提及列的简单插入:
当表(#table2)的选定列数等于插入表(Table1)时的批量插入
当您只想插入表中所需的列时,批量插入(表格1):
Simple insertion when table column sequence is known:
Simple insertion mentioning column:
Bulk insertion when number of selected columns of a table(#table2) are equal to insertion table(Table1)
Bulk insertion when you want to insert only into desired column of a table(table1):
大多数数据库都遵循基本语法,
我使用过的每个数据库都遵循这种语法,即
DB2
、SQL Server
、MY SQL
、PostgresQL
Most of the databases follow the basic syntax,
Every database I have used follow this syntax namely,
DB2
,SQL Server
,MY SQL
,PostgresQL
为了从另一个表中获取多值 INSERT 中的一个值,我在 SQLite3 中执行了以下操作:
To get only one value in a multi value
INSERT
from another table I did the following in SQLite3:我看到的两个答案在 Informix 中都工作得很好,并且基本上都是标准 SQL。 也就是说,符号:
可以很好地与 Informix 配合使用,并且我希望与所有 DBMS 配合使用。 (在 5 年前或更多年前,MySQL 并不总是支持这种事情;现在它对这种标准 SQL 语法提供了很好的支持,而且,据我所知,它在这种表示法上可以正常工作。)是可选的,但按顺序指示目标列,因此 SELECT 结果的第一列将进入第一个列出的列,依此类推。在没有列列表的情况下,SELECT 结果的第一列进入目标表的第一列。
系统之间的不同之处在于用于标识不同数据库中的表的符号 - 该标准没有提及数据库间(更不用说 DBMS 间)操作。 使用 Informix,您可以使用以下表示法来标识表:
也就是说,您可以指定一个数据库,如果该数据库不在当前服务器中,则可以选择标识托管该数据库的服务器,后跟可选的所有者、点,最后实际的表名。 SQL 标准使用术语模式来表示 Informix 所称的所有者。 因此,在 Informix 中,以下任何符号都可以标识表:
所有者通常不需要加引号; 但是,如果您确实使用引号,则需要正确拼写所有者名称 - 它区分大小写。 即:
都标识同一个表。 对于 Informix,MODE ANSI 数据库有一个轻微的复杂性,其中所有者名称通常转换为大写(informix 是例外)。 也就是说,在 MODE ANSI 数据库(不常用)中,您可以编写:
并且系统目录中的所有者名称将是“SOMEONE”,而不是“someone”。 如果将所有者名称括在双引号中,则它的作用类似于分隔标识符。 对于标准 SQL,分隔标识符可以在很多地方使用。 使用 Informix,您只能在所有者名称周围使用它们——在其他上下文中,Informix 将单引号和双引号字符串都视为字符串,而不是将单引号字符串视为字符串,将双引号字符串视为分隔标识符。 (当然,为了完整起见,有一个环境变量 DELIMIDENT,可以设置为任何值,但 Y 是最安全的 - 指示双引号始终包围定界标识符,单引号始终包围字符串。)
请注意,MS SQL Server 设法使用方括号括起来的[分隔标识符]。 它对我来说看起来很奇怪,并且肯定不是 SQL 标准的一部分。
Both the answers I see work fine in Informix specifically, and are basically standard SQL. That is, the notation:
works fine with Informix and, I would expect, all the DBMS. (Once upon 5 or more years ago, this is the sort of thing that MySQL did not always support; it now has decent support for this sort of standard SQL syntax and, AFAIK, it would work OK on this notation.) The column list is optional but indicates the target columns in sequence, so the first column of the result of the SELECT will go into the first listed column, etc. In the absence of the column list, the first column of the result of the SELECT goes into the first column of the target table.
What can be different between systems is the notation used to identify tables in different databases - the standard has nothing to say about inter-database (let alone inter-DBMS) operations. With Informix, you can use the following notation to identify a table:
That is, you may specify a database, optionally identifying the server that hosts that database if it is not in the current server, followed by an optional owner, dot, and finally the actual table name. The SQL standard uses the term schema for what Informix calls the owner. Thus, in Informix, any of the following notations could identify a table:
The owner in general does not need to be quoted; however, if you do use quotes, you need to get the owner name spelled correctly - it becomes case-sensitive. That is:
all identify the same table. With Informix, there's a mild complication with MODE ANSI databases, where owner names are generally converted to upper-case (informix is the exception). That is, in a MODE ANSI database (not commonly used), you could write:
and the owner name in the system catalog would be "SOMEONE", rather than 'someone'. If you enclose the owner name in double quotes, it acts like a delimited identifier. With standard SQL, delimited identifiers can be used many places. With Informix, you can use them only around owner names -- in other contexts, Informix treats both single-quoted and double-quoted strings as strings, rather than separating single-quoted strings as strings and double-quoted strings as delimited identifiers. (Of course, just for completeness, there is an environment variable, DELIMIDENT, that can be set - to any value, but Y is safest - to indicate that double quotes always surround delimited identifiers and single quotes always surround strings.)
Note that MS SQL Server manages to use [delimited identifiers] enclosed in square brackets. It looks weird to me, and is certainly not part of the SQL standard.
尝试:
这是标准 ANSI SQL,应该适用于任何 DBMS
它绝对适用于:
Try:
This is standard ANSI SQL and should work on any DBMS
It definitely works for:
Claude Houle 的答案:应该可以正常工作,而且您也可以拥有多个列和其他数据:
我只使用过Access、SQL 2000/2005/Express、MySQL 和 PostgreSQL 都使用此语法,因此应该涵盖这些语法。 它也应该与 SQLite3 一起使用。
Claude Houle's answer: should work fine, and you can also have multiple columns and other data as well:
I've only used this syntax with Access, SQL 2000/2005/Express, MySQL, and PostgreSQL, so those should be covered. It should also work with SQLite3.
只需使用
SELECT
查询,而不是INSERT
查询的VALUES
部分,如下所示。Instead of
VALUES
part ofINSERT
query, just useSELECT
query as below.要在第一个答案中添加一些内容,当我们只需要另一个表中的几条记录(在本例中只有一条)时:
To add something in the first answer, when we want only few records from another table (in this example only one):
使用 select 子查询插入的两种方法。
1. 使用 SELECT 子查询返回一行结果的方法。
在这种情况下,它假设 SELECT 子查询基于 WHERE 条件或 SUM、MAX 等 SQL 聚合函数仅返回一行结果,AVG等。否则会抛出错误
2。 使用 SELECT 子查询返回多行结果的方法。
第二种方法适用于这两种情况。
Two approaches for insert into with select sub-query.
1. Approach for With SELECT subquery returning results with one row.
In this case, it assumes SELECT Sub-query returns only one row of result based on WHERE condition or SQL aggregate functions like SUM, MAX, AVG etc. Otherwise it will throw error
2. Approach for With SELECT subquery returning results with multiple rows.
The second approach will work for both the cases.