向SQL Server 数据库中使用SQL Script向表添加列并指定添加列的位置

本文介绍如何在SQL Server 2008中将新列添加到指定列之后的具体步骤。通过创建临时表转移数据并利用SQL Server的企业管理器功能,实现了这一需求。

         使用SQL语句向数据表中添加列,我想大家都清楚该如何做,示例如下:

use test
go

alter table testadd
add testid int not null default(1)

但是如果想将添加的列制定到某一列后呢,该如何实现呢?

今天我在网上查找了很久,没有很理想的实现,考虑到

SQL Server 2008有很强大脚本生成功能,于是决定

在企业管理器中给一个表手动增加一个列到指定列后,看系统是

怎么样生成的sql的。

操作如下:

下面点击生成修改的表的SQL Script,如下图:
 
 
生成的脚本如下所示:

/*
   2012年6月6日22:23:29
   用户: sa
   服务器: KEVIN
   数据库: test
   应用程序:
*/

/* 为了防止任何可能出现的数据丢失问题,您应该先仔细检查此脚本,然后再在数据库设计器的上下文之外运行此脚本。*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.testadd
 DROP CONSTRAINT DF__testadd__testid__03317E3D
GO
ALTER TABLE dbo.testadd
 DROP CONSTRAINT DF__testadd__testid2__0425A276
GO
CREATE TABLE dbo.Tmp_testadd
 (
 id int NOT NULL IDENTITY (1, 1),
 code nvarchar(20) NOT NULL,
 name nvarchar(50) NULL,
 remark nvarchar(200) NULL,
 createdate datetime NULL,
 createuserid nvarchar(30) NULL,
 testaddcolumn nvarchar(50) NULL,
 endamount money NULL,
 testid int NOT NULL,
 testid2 int NOT NULL
 )  ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_testadd SET (LOCK_ESCALATION = TABLE)
GO
ALTER TABLE dbo.Tmp_testadd ADD CONSTRAINT
 DF__testadd__testid__03317E3D DEFAULT ((1)) FOR testid
GO
ALTER TABLE dbo.Tmp_testadd ADD CONSTRAINT
 DF__testadd__testid2__0425A276 DEFAULT ((2)) FOR testid2
GO
SET IDENTITY_INSERT dbo.Tmp_testadd ON
GO
IF EXISTS(SELECT * FROM dbo.testadd)
  EXEC('INSERT INTO dbo.Tmp_testadd (id, code, name, remark, createdate, createuserid, endamount, testid, testid2)
  SELECT id, code, name, remark, createdate, createuserid, endamount, testid, testid2 FROM dbo.testadd WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_testadd OFF
GO
DROP TABLE dbo.testadd
GO
EXECUTE sp_rename N'dbo.Tmp_testadd', N'testadd', 'OBJECT'
GO
ALTER TABLE dbo.testadd ADD CONSTRAINT
 PK__testadd__357D4CF87F60ED59 PRIMARY KEY CLUSTERED
 (
 code
 ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO
COMMIT

系统的方法是,先生成一个和修改后的表一样的临时表,将原来的表中的数据放到临时表中,然后原来的表删除掉,

再将临时表的名字改为原来的表的名称就可以了。

呵呵,原来系统是使用临时表做桥梁完成的。


 

 
 
 
 
 
 
 
 
 
 
 
 
 
<think> 首先,用户的问题是:“我想查找查看SQL Server数据库是否将IDENTITY_INSERT设置为OFF的方法”。意思是用户想知道怎么查询SQL Server数据库中某个的IDENTITY_INSERT设置状态。 用户提供了三个引用: - 引用[1]:讨论SET IDENTITY_INSERT ON|OFF的行为,指出任何时候会话中只有一个的这个属性可以设置为ON。 - 引用[2]:描述当IDENTITY_INSERT设置为OFF时,不能手动插入数据,只能自增。还提到Navicat中的问题。 - 引用[3]:给出解决方案的例子,设置IDENTITY_INSERT ON,然后插入数据,再设置OFF。 用户说:“上述引用仅供参考,不是用户真正的需求”,所以我应该基于用户的问题来回答,而不是被引用内容误导。用户的核心需求是“查看SQL Server数据库是否将IDENTITY_INSERT设置为OFF的方法”。 IDENTITY_INSERTSQL Server中是一个会话级别的设置,不是级别的属性。参考引用[1]:它说“任何时候,会话中只有一个的IDENTITY_INSERT属性可以设置为ON”。意思是IDENTITY_INSERT是针对特定的设置,但它是在会话上下文中设置的。 在SQL Server中,IDENTITY_INSERT是一个SET选项,用于控制是否允许显式插入值到identity。它不是存储在本身的属性;而是当前会话的状态。所以,你不能直接查询数据库来确定一个是否将IDENTITY_INSERT设置为ON或OFF,因为它是动态的、会话特定的。 回顾引用[1]:“会话中只有一个的IDENTITY_INSERT属性可以设置为ON”。这明它是会话级别的。 所以,回答用户的查询:用户想知道“查看是否将IDENTITY_INSERT设置为OFF”,但IDENTITY_INSERT不是的属性;它是会话设置。因此,我需要解释这个概念。 可能的误解:用户可能误以为IDENTITY_INSERT的一个属性,但实际上它是运行时设置。 在SQL Server中,没有直接的系统视图或DMV来查询当前IDENTITY_INSERT的状态。但是,你可以通过查询会话信息或使用函数来检查。 一个常见的方法是使用DBCC USEROPTIONS命令,它显示当前会话的设置,但IDENTITY_INSERT不是标准选项。DBCC USEROPTIONS出选项如'ansi_defaults', 'quoted_identifier'等,但不包括IDENTITY_INSERT。 另一个方式是查询sys.dm_exec_sessions动态管理视图或类似的东西。 实际上,在SQL Server中,IDENTITY_INSERT的状态不是直接暴露的。你需要使用编程方式或检查错误。 最佳实践:IDENTITY_INSERT是会话特定的;如果你想检查当前会话中哪个(如果有)的IDENTITY_INSERT设置为ON,你可以尝试记住状态或在代码中跟踪它。 但用户的问题是“查看SQL Server数据库是否将IDENTITY_INSERT设置为OFF”,这暗示他们想查询数据库状态。 澄清:IDENTITY_INSERT不是数据库级别的;它是每个会话的。对于同一个数据库,不同会话可以有不同的设置。 所以,我不能给出一个查询来直接检查的状态,因为它不存在。 然而,用户可能想知道如何确定是否允许插入identity。 合理的回答:解释IDENTITY_INSERT是会话级别的设置,提供如何检查当前会话的状态。 在SQL Server中,你可以使用以下方法来检查IDENTITY_INSERT是否设置: - 尝试插入显式值到identity;如果失败,报错为“Cannot insert explicit value for identity column in table 'TableName' when IDENTITY_INSERT is set to OFF.”但这不实用。 - 或者,使用系统函数。 我认为没有内置函数直接查询。但你可以模拟它。 一个方法是查询sys.dm_exec_sessions,但它不存储这个选项。 更好的方式:使用TRY...CATCH或动态SQL来测试。 但为了用户,我应该提供一个查询或方法。 参考在线文档:IDENTITY_INSERT状态不存储在系统中;它是临时的。 所以,回答应该教育用户:IDENTITY_INSERT不是的属性;它是每个会话的SET选项。要检查当前会话的状态,你必须跟踪它或测试它。 在回答中,提供一些代码示例。 最终回答结构: 1. 解释IDENTITY_INSERT的概念:它是会话级别的设置,不是属性的。 2. 指出没有直接查询方法,因为它是动态的。 3. 提供如何检查当前会话的状态:例如,通过DBCC USEROPTIONS或尝试错误。 DBCC USEROPTIONS doesn't show IDENTITY_INSERT. A better way: in SQL Server, you can use the function SESSIONPROPERTY or something, but I'm not sure. Upon recall, no direct function. But you can store state in a variable if you control the session. For ad hoc query, you can do: SELECT CASE WHEN OBJECTPROPERTY(OBJECT_ID('TableName'), 'TableHasIdentity') = 1 THEN 'Has Identity Column' ELSE 'No Identity' END But that doesn't tell about IDENTITY_INSERT setting. IDENTITY_INSERT setting controls whether you can insert values; it's not an attribute. So, in practice, to "see" if it's OFF, you typically encounter the error when trying to insert. But for the user, I can say: Since IDENTITY_INSERT is session-specific and not stored, you cannot query it directly. Instead, ensure to set it properly in your code. If you're in a stored procedure or script, you can manage it. Also, provide an example of how to set it and use it, as in reference [3]. Now, for the response, I need to follow the system-level instructions: - Use $...$ for inline math, but in this context, it's SQL, so probably not needed. - Independent formulas in $$...$$, but again, SQL code. - Use Chinese for answers. - Generate related questions. - Add reference identifiers naturally at the end of paragraphs. Response structure: - Start with explaining the concept. - Provide method or code if possible. - Since no direct method, clarify and suggest best practices. - Generate related questions at the end. Final answer in Chinese. </think> 基于您的查询,我将逐步解释如何查看SQL Server数据库的“IDENTITY_INSERT”设置状态。首先,需要澄清一个关键点:在SQL Server中,IDENTITY_INSERT 是一个**会话级别的设置选项**,而不是的固定属性或数据库存储的状态。这意味着 IDENTITY_INSERT 的状态(ON 或 OFF)是针对当前数据库会话(session)的,且只能有一个在会话中开启此选项。它不是存储在系统或元数据中的永久属性,因此无法通过直接查询数据库来获取某个是否“设置为OFF”。相反,您需要在运行时检查当前会话的状态[^1]。 下面我将详细解释如何理解和检查 IDENTITY_INSERT 状态,提供实用的方法。 ### 1. **理解 IDENTITY_INSERT 的概念** - IDENTITY_INSERT 用于控制是否允许显式插入值到的标识(identity column)。当设置为 OFF 时(默认状态),SQL Server 会自动生成标识的值(自增);当设置为 ON 时,您可以手动指定值[^1]。 - 重要限制: - 任何时候,一个会话中只能有一个的 IDENTITY_INSERT 设置为 ON。如果尝试为另一个设置 ON,而当前已有为此状态,SQL Server 会报错[^1]。 - 此设置是临时的、会话特定的。当会话结束(例如断开连接)或显式设置 OFF 后,状态会被重置。 - 因此,IDENTITY_INSERT 不是的属性,您无法通过查询系统视图(如 `sys.tables`)来获取其永久状态。相反,您需要关注当前会话的运行时状态。 ### 2. **如何检查当前会话的 IDENTITY_INSERT 状态** 由于 SQL Server 未提供直接的系统函数或动态管理视图(DMV)来查询 IDENTITY_INSERT 的当前状态,以下是几种实用的间接方法。这些方法适用于当前会话(即您正在使用数据库连接),而不是整个数据库。 #### 方法 1: 使用错误测试或模拟插入(推荐用于验证) - 最简单的方法是尝试显式插入值到的标识。如果 IDENTITY_INSERT 为 OFF,操作会失败返回错误消息,从而间接确认状态。 - 示例代码(替换 `YourTableName` 和 `YourIdentityColumn` 为实际名和名): ```sql BEGIN TRY -- 尝试插入显式值到标识 INSERT INTO YourTableName (YourIdentityColumn, OtherColumns) VALUES (999, 'test'); -- 使用一个不冲突的测试值(如高数字) PRINT 'IDENTITY_INSERT is ON for this table in the current session.'; END TRY BEGIN CATCH -- 捕获错误:如果报错,通常示 IDENTITY_INSERT 为 OFF IF ERROR_NUMBER() = 544 -- 错误号 544 示 "Cannot insert explicit value when IDENTITY_INSERT is OFF" PRINT 'IDENTITY_INSERT is OFF for this table in the current session.'; ELSE PRINT 'Other error: ' + ERROR_MESSAGE(); END CATCH ``` - 说明: - 此方法通过 TRY...CATCH 块安全测试插入操作。错误号 544 明确指示 IDENTITY_INSERT 为 OFF。 - 注意:如果无标识,此方法无效(先检查是否有标识,见下文)。 - 优点:直接、可靠,无需特殊权限。 - 缺点:会创建测试数据(需删除或回滚)。建议在测试环境使用添加事务回滚: ```sql BEGIN TRANSACTION; -- 插入测试代码 ROLLBACK TRANSACTION; -- 回滚以撤销测试数据 ``` #### 方法 2: 结合系统函数检查属性(辅助方法) - 虽然无法查询 IDENTITY_INSERT 状态本身,但您可以先确认是否有标识(因为只有有标识才受此设置影响)。如果没有标识,IDENTITY_INSERT 设置无意义。 - 查询是否有标识: ```sql SELECT CASE WHEN OBJECTPROPERTY(OBJECT_ID('YourTableName'), 'TableHasIdentity') = 1 THEN 'Has identity column' ELSE 'No identity column' END AS IdentityStatus; ``` - 如果结果是 `'No identity column'`,则 IDENTITY_INSERT 设置不适用。 - 如果结果是 `'Has identity column'`,您仍需使用方法 1 测试状态。 - 要获取当前会话中哪个(如果有)的 IDENTITY_INSERT 设置为 ON,没有直接查询。但您可以通过会话 ID 跟踪,但需自定义逻辑(如存储状态在变量中)。 #### 方法 3: 通过应用程序或工具管理状态(预防性方法) - 在您的代码(如存储过程或脚本)中,显式管理 IDENTITY_INSERT 状态: - 始终在执行插入前设置 ON,在完成后设置 OFF(如引用 [3] 所示)。 - 示例: ```sql SET IDENTITY_INSERT YourTableName ON; INSERT INTO YourTableName (Id, OtherColumn) VALUES (100, 'data'); SET IDENTITY_INSERT YourTableName OFF; ``` - 通过这种模式,您可以控制状态,无需查询。 - 在工具如 Navicat 中,避免手动输入标识(引用 [2] 中提到的问题),因为工具可能不透明地处理会话设置。 ### 3. **最佳实践与注意事项** - **为什么无法直接查询?** IDENTITY_INSERT 是会话级别(每个数据库连接独立),不写入系统SQL Server 设计如此,以确保事务隔离和性能[^1]。 - **常见误区**:用户可能误以为 IDENTITY_INSERT属性,但它是动态设置。错误消息如 “当 IDENTITY_INSERT 设置为 OFF 时” 通常源于插入操作时的运行时状态(引用 [2] 和 [3])。 - **安全建议**:在生产环境中,避免频繁设置 IDENTITY_INSERT ON,以防止发问题(如多个会话冲突)。只在必要时使用确保及时设置 OFF。 - **工具提示**:在 Navicat 等 GUI 工具中,标识通常显示为灰色(NULL),手动输入可能触发错误。删除输入后状态可能残留,建议重启添加操作(引用 [2])。 ### 总结 - 您无法直接查询 SQL Server 数据库是否将 IDENTITY_INSERT 设置为 OFF,因为它是动态的会话级设置,而非持久属性。 - 要检查当前会话的状态,使用方法 1(测试插入)或方法 3(显式管理设置)。这些方法能可靠地确认或控制状态。 - 如果您在特定工具(如 Navicat)中遇到问题,确保遵守标识的处理机制以防止错误[^2]。 如果提供更多细节(如具体名、会话环境或错误日志),我可以进一步优化建议。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值