简体   繁体   English

T-SQL插入表中而不必指定每一列

[英]T-SQL Insert into table without having to specify every column

In our db there is a table that has a little over 80 columns. 在我们的数据库中,有一个表有80多个列。 It has a primary key and Identity insert is turned on. 它有一个主键,并打开标识插入。 I'm looking for a way to insert into this table every column EXCEPT the primary key column from an identical table in a different DB. 我正在寻找一种方法来插入此表中的每一列除了来自不同数据库中相同表的主键列之外。

Is this possible? 这可能吗?

You can do this quite easily actually: 你可以很容易地做到这一点:

-- Select everything into temp table
Select * Into 
    #tmpBigTable
    From [YourBigTable]

-- Drop the Primary Key Column from the temp table  
Alter Table #tmpBigTable Drop Column [PrimaryKeyColumn]

-- Insert that into your other big table
Insert Into [YourOtherBigTable]
    Select * From #tmpBigTable

-- Drop the temp table you created
Drop Table #tmpBigTable

Provided you have Identity Insert On in "YourOtherBigTable" and columns are absolutely identical you will be okay. 如果您在“YourOtherBigTable”中有Identity Insert On并且列完全相同,那么您将没问题。

CREATE TABLE Tests
(
    TestID int IDENTITY PRIMARY KEY,
    A int,
    B int,
    C int
)

INSERT INTO dbo.Tests
VALUES (1,2,3)

SELECT * FROM Tests

This works in SQL2012 这适用于SQL2012

You could query Information_Schema to get a list of all the columns and programatically generate the column names for your query. 您可以查询Information_Schema以获取所有列的列表,并以编程方式生成查询的列名称。 If you're doing this all in t-sql it would be cumbersome, but it could be done. 如果你在t-sql中做这一切都会很麻烦,但是可以做到。 If you're using some other client language, like C# to do the operation, it would be a little less cumbersome. 如果你正在使用其他一些客户端语言,比如C#来进行操作,那就不那么麻烦了。

No, that's not possible. 不,那是不可能的。 You could be tempted to use 你可能会被诱惑使用

INSERT INTO MyLargeTable SELECT * FROM OtherTable

But that would not work, because your identity column would be included in the *. 但这不起作用,因为您的标识列将包含在*中。

You could use 你可以用

SET IDENTITY_INSERT MyLargeTable ON
INSERT INTO MyLargeTable SELECT * FROM OtherTable
SET IDENTITY_INSERT MyLargeTable OFF

first you enable inserting identity values, than you copy the records, then you enable the identity column again. 首先启用插入标识值,而不是复制记录,然后再次启用标识列。

But this won't work neither. 但这也不会奏效。 SQL server won't accept the * in this case. 在这种情况下,SQL Server不接受*。 You have to explicitly include the Id in the script, like : 您必须在脚本中明确包含Id,例如:

SET IDENTITY_INSERT MyLargeTable ON
INSERT INTO MyLargeTable (Id, co1, col2, ...., col80) SELECT Id, co1, col2, ...., col80 FROM OtherTable
SET IDENTITY_INSERT MyLargeTable OFF

So we're back from where we started. 所以我们从我们开始的地方回来了。

The easiest way is to right click the table in Management Studio, let it generate the INSERT and SELECT scripts, and edit them a little to let them work together. 最简单的方法是右键单击Management Studio中的表,让它生成INSERT和SELECT脚本,然后稍微编辑它们以使它们一起工作。

Why not just create a VIEW of the original data, removing the unwanted fields? 为什么不创建原始数据的VIEW,删除不需要的字段? Then 'Select * into' your hearts desire. 然后'选择*进入'你的心愿。

  • Localized control within a single view 单个视图中的本地化控制
  • No need to modify SPROC 无需修改SPROC
  • Add/change/delete fields easy 轻松添加/更改/删除字段
  • No need to query meta-data 无需查询元数据
  • No temporary tables 没有临时表

Really, honestly it takes ten seconds or less to pull all of the columns over from the object browser and then delete the identity column from the list. 说实话,从对象浏览器中拉出所有列需要十秒或更短时间,然后从列表中删除标识列。 It is a bad idea to use select * for anything but quick ad hoc query. 除了快速的即席查询之外,使用select *进行任何操作都是一个坏主意。

In answer to a related question ( SELECT * EXCEPT ), I point out the truly relational language Tutorial D allows projection to be expressed in terms of the attributes to be removed instead of the ones to be kept eg 在回答相关问题( SELECT * EXCEPT )时,我指出真正的关系语言Tutorial D允许用要删除的属性表示投影,而不是要保留的属性,例如

my_relvar { ALL BUT description }

However its INSERT syntax requires tuple value constructors to include attribute name / value pairs eg 但是,其INSERT语法要求元组值构造函数包含属性名称/值对,例如

INSERT P
   RELATION 
   {
      TUPLE { PNO PNO ( 'P1' ) , PNAME CHARACTER ( 'Nut' ) }, 
      TUPLE { PNO PNO ( 'P2' ) , PNAME CHARACTER ( 'Bolt' ) }
   };

Of course, using this syntax there is no column ordering (because it is truly relational!) eg this is semantically equivalent: 当然,使用这种语法没有列排序(因为它是真正的关系!),例如,这在语义上是等价的:

INSERT P
   RELATION 
   {
      TUPLE { PNO PNO ( 'P1' ) , PNAME CHARACTER ( 'Nut' ) }, 
      TUPLE { PNAME CHARACTER ( 'Bolt' ) , PNO PNO ( 'P2' ) }
   };

The alternative would be to rely fully on attribute ordering, which SQL does partially eg this is a close SQL equivalent to the the above: 另一种方法是完全依赖属性排序,SQL会部分地进行,例如,这是一个与上述相同的紧密SQL:

INSERT INTO P ( PNO , PNAME ) 
   VALUES        
      ( PNO ( 'P1' ) , CAST ( 'Nut'  AS VARCHAR ( 20 ) ) ) , 
      ( PNO ( 'P2' ) , CAST ( 'Bolt' AS VARCHAR ( 20 ) ) );

Once the commalist of columns has been specified the VALUES row constructors have the maintain this order, which is not ideal. 一旦指定了列的commalist, VALUES行构造函数就会维护此顺序,这并不理想。 But at least the order is specified: your proposal would rely on some default order which may be possibly non-deterministic. 但至少指定了订单:您的提案将依赖于某些默认订单,这可能是非确定性的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM