使用SQL Server时经常用到的几个设置选项

本文介绍 SQL Server 中的会话配置选项,包括死锁优先级、锁超时、标识插入、隐性事务等设置的语法、作用及示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. SET DEADLOCK_PRIORITY
  2. SET LOCK_TIMEOUT
  3.@@LOCK_TIMEOUT
  4.SET IDENTITY_INSERT
  5.SET IMPLICIT_TRANSACTIONS
  6.SET NOCOUNT
  7.@@ROWCOUNT
  8.SET ROWCOUNT
  9.SET TRANSACTION ISOLATION LEVEL
  10.SET XACT_ABORT

  1. SET DEADLOCK_PRIORITY

  说明:控制在发生死锁情况时会话的反应方式。如果两个进程都锁定数据,并且直到其它进程释放自己的锁时,每个进程才能释放自己的锁,即发生死锁情况。

  语法:SET DEADLOCK_PRIORITY { LOW | NORMAL | @deadlock_var }

  参数:LOW  指定当前会话为首选死锁牺牲品。Microsoft® SQL Server™ 自动回滚死锁牺牲品的事务,并给客户端应用程序返回 1205 号死锁错误信息。
  NORMAL  指定会话返回到默认的死锁处理方法。
  @deadlock_var 是指定死锁处理方法的字符变量。如果指定 LOW,则 @deadlock_var 为 3;如果指定 NORMAL,则 @deadlock_var 为 6。

  注释:SET DEADLOCK_PRIORITY 的设置是在执行或运行时设置,而不是在分析时设置。

  权限:SET DEADLOCK_PRIORITY 权限默认授予所有用户。

  2. SET LOCK_TIMEOUT

  说明:指定语句等待锁释放的毫秒数。

  语法:SET LOCK_TIMEOUT timeout_period

  参数:timeout_period 是在 Microsoft® SQL Server™ 返回锁定错误前经过的毫秒数。值为 -1(默认值)时表示没有超时期限(即无限期等待)。
  当锁等待超过超时值时,将返回错误。值为 0 时表示根本不等待,并且一遇到锁就返回信息。

  注释:在连接开始时,该设置的值为 -1。设置更改后,新设置在其余的连接时间里一直有效。
  SET LOCK_TIMEOUT 的设置是在执行或运行时设置,而不是在分析时设置。
  READPAST 锁定提示为该 SET 选项提供了另一种方式。

  权限:SET LOCK_TIMEOUT 权限默认授予所有用户。

  示例:下例将锁超时期限设置为 1,800 毫秒。

  SET LOCK_TIMEOUT 1800
  GO

  3. @@LOCK_TIMEOUT

  说明:返回当前会话的当前锁超时设置,单位为毫秒。

  语法:@@LOCK_TIMEOUT

  返回类型:integer

  注释:SET LOCK_TIMEOUT 允许应用程序设置语句等待阻塞资源的最长时间。当一条语句已等待超过 LOCK_TIMEOUT 所设置的时间,则被锁住的语句将自动取消,并给应用程序返回一条错误信息。
  在一个连接的开始,@@LOCK_TIMEOUT 返回一个 –1值。

  示例:下面的示例显示当一个 LOCK_TIMEOUT 值未被设置时的结果集。

  SELECT @@LOCK_TIMEOUT
  下面是结果集:
  ----------------
  -1

  下面的示例设置 LOCK_TIMEOUT 为 1800 毫秒,然后调用 @@LOCK_TIMEOUT。

  SET LOCK_TIMEOUT 1800
  SELECT @@LOCK_TIMEOUT

  下面是结果集:
  ------------------------------
  1800

  4. SET IDENTITY_INSERT

  说明:允许将显式值插入表的标识列中。

  语法:SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }

  参数:database 是指定的表所驻留的数据库名称。
  owner 是表所有者的名称。
  table 是含有标识列的表名。

  注释:任何时候,会话中只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则 Microsoft® SQL Server™ 返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为 ON 的表。
  如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用。
  SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置。

  权限:执行权限默认授予 sysadmin 固定服务器角色和 db_owner 及 db_ddladmin 固定数据库角色以及对象所有者。

  示例:下例创建一个含有标识列的表,并显示如何使用 SET IDENTITY_INSERT 设置填充由 DELETE 语句导致的标识值中的空隙。

  -- Create products table.
  CREATE TABLE products (id int IDENTITY PRIMARY KEY, product varchar(40))
  GO
  -- Inserting values into products table.
  INSERT INTO products (product) VALUES ('screwdriver')
  INSERT INTO products (product) VALUES ('hammer')
  INSERT INTO products (product) VALUES ('saw')
  INSERT INTO products (product) VALUES ('shovel')
  GO

  -- Create a gap in the identity values.
  DELETE products 
  WHERE product = 'saw'
  GO

  SELECT * 
  FROM products
  GO

  -- Attempt to insert an explicit ID value of 3;
  -- should return a warning.
  INSERT INTO products (id, product) VALUES(3, 'garden shovel')
  GO

  -- SET IDENTITY_INSERT to ON.
  SET IDENTITY_INSERT products ON
  GO

  -- Attempt to insert an explicit ID value of 3
  INSERT INTO products (id, product) VALUES(3, 'garden shovel')
  GO

  SELECT * 
  FROM products
  GO

  -- Drop products table.
  DROP TABLE products
  GO

  5. SET IMPLICIT_TRANSACTIONS

  说明:为连接设置隐性事务模式。

  语法:SET IMPLICIT_TRANSACTIONS { ON | OFF }

  注释:当设置为 ON 时,SET IMPLICIT_TRANSACTIONS 将连接设置为隐性事务模式。当设置为 OFF 时,则使连接返回到自动提交事务模式。
  当连接是隐性事务模式且当前不在事务中时,执行下列语句将启动事务:

  ALTER TABLE FETCH REVOKE 
  CREATE  GRANT SELECT 
  DELETE INSERT TRUNCATE TABLE 
  DROP OPEN UPDATE 

  如果连接已经在打开的事务中,则上述语句不启动新事务。
  对于因为该设置为 ON 而自动打开的事务,用户必须在该事务结束时将其显式提交或回滚。否则当用户断开连接时,事务及其所包含的所有数据更改将回滚。在事务提交后,执行上述任一语句即可启动新事务。
  隐性事务模式将保持有效,直到连接执行 SET IMPLICIT_TRANSACTIONS OFF 语句使连接返回到自动提交模式。在自动提交模式下,如果各个语句成功完成则提交。
  在进行连接时,SQL Server ODBC 驱动程序和用于 SQL Server 的 Microsoft OLE DB 提供程序自动将 IMPLICIT_TRANSACTIONS 设置为 OFF。对来自 DB-Library 应用程序的连接,SET IMPLICIT_TRANSACTIONS 默认为 OFF。
  当 SET ANSI_DEFAULTS 为 ON 时,将启用 SET IMPLICIT_TRANSACTIONS。
  SET IMPLICIT_TRANSACTIONS 的设置是在执行或运行时设置,而不是在分析时设置。

  示例:下例演示在将 IMPLICIT_TRANSACTIONS 设置为 ON 时显式或隐式启动事务。它使用 @@TRANCOUNT 函数演示打开的事务和关闭的事务。

  USE pubs
  GO

  CREATE table t1 (a int)
  GO
  INSERT INTO t1 VALUES (1)
  GO

  PRINT 'Use explicit transaction'
  BEGIN TRAN
  INSERT INTO t1 VALUES (2)
  SELECT 'Tran count in transaction'= @@TRANCOUNT
  COMMIT TRAN
  SELECT 'Tran count outside transaction'= @@TRANCOUNT
  GO

  PRINT 'Setting IMPLICIT_TRANSACTIONS ON'
  GO
  SET IMPLICIT_TRANSACTIONS ON
  GO

  PRINT 'Use implicit transactions'
  GO
  -- No BEGIN TRAN needed here.
  INSERT INTO t1 VALUES (4)
  SELECT 'Tran count in transaction'= @@TRANCOUNT
  COMMIT TRAN
  SELECT 'Tran count outside transaction'= @@TRANCOUNT
  GO

  PRINT 'Use explicit transactions with IMPLICIT_TRANSACTIONS ON'
  GO
  BEGIN TRAN
  INSERT INTO t1 VALUES (5)
  SELECT 'Tran count in transaction'= @@TRANCOUNT
  COMMIT TRAN
  SELECT 'Tran count outside transaction'= @@TRANCOUNT
  GO

  SELECT * FROM t1
  GO

6. SET NOCOUNT
  说明:使返回的结果中不包含有关受 Transact-SQL 语句影响的行数的信息。

  语法:SET NOCOUNT { ON | OFF } 

  注释:当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数)。当 SET NOCOUNT 为 OFF 时,返回计数。
  即使当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。
  当 SET NOCOUNT 为 ON 时,将不给客户端发送存储过程中的每个语句的 DONE_IN_PROC 信息。当使用 Microsoft® SQL Server™ 提供的实用工具执行查询时,在 Transact-SQL 语句(如 SELECT、INSERT、UPDATE 和 DELETE)结束时将不会在查询结果中显示"nn rows affected"。
  如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。
  SET NOCOUNT 设置是在执行或运行时设置,而不是在分析时设置。

  权限:SET NOCOUNT 权限默认授予所有用户。

  示例:下例在 osql 实用工具或 SQL Server 查询分析器中执行时,可防止显示有关受影响的行数的信息。

  USE pubs
  GO
  -- Display the count message.
  SELECT au_lname 
  FROM authors
  GO
  USE pubs
  GO
  -- SET NOCOUNT to ON and no longer display the count message.
  SET NOCOUNT ON
  GO
  SELECT au_lname 
  FROM authors
  GO
  -- Reset SET NOCOUNT to OFF.
  SET NOCOUNT OFF
  GO

  7. @@ROWCOUNT
  说明:返回受上一语句影响的行数。

  语法:@@ROWCOUNT

  返回类型:integer

  注释:任何不返回行的语句将这一变量设置为 0 ,如 IF 语句。

  示例:下面的示例执行 UPDATE 语句并用 @@ROWCOUNT 来检测是否有发生更改的行。

  UPDATE authors SET au_lname = 'Jones'
  WHERE au_id = '999-888-7777'
  IF @@ROWCOUNT = 0
     print 'Warning: No rows were updated'

  8. SET ROWCOUNT

  说明:使 Microsoft® SQL Server™ 在返回指定的行数之后停止处理查询。 

  语法:SET ROWCOUNT { number | @number_var } 

  参数:number | @number_var 是在停止给定查询之前要处理的行数(整数)。

  注释:建议将当前使用 SET ROWCOUNT 的 DELETE、INSERT 和 UPDATE 语句重新编写为使用 TOP 语法。有关更多信息,请参见 DELETE、INSERT 或 UPDATE。
  对于在远程表和本地及远程分区视图上执行的 INSERT、UPDATE 和 DELETE 语句,忽略 SET ROWCOUNT 选项设置。
  若要关闭该选项(以便返回所有的行),请将 SET ROWCOUNT 指定为 0。
  说明  设置 SET ROWCOUNT 选项将使大多数 Transact-SQL 语句在已受指定数目的行影响后停止处理。这包括触发器和 INSERT、UPDATE 及 DELETE 等数据修改语句。ROWCOUNT 选项对动态游标无效,但限制键集的行集和不感知游标。使用该选项时应谨慎,它主要与 SELECT 语句一起使用。
  如果行数的值较小,则 SET ROWCOUNT 替代 SELECT 语句 TOP 关键字。
  SET ROWCOUNT 的设置是在执行或运行时设置,而不是在分析时设置。

  权限:SET ROWCOUNT 权限默认授予所有用户。

  示例:SET ROWCOUNT 在指定的行数后停止处理。在下例中,注意有 x 行满足预付款少于或等于 $5,000 的条件;但是,从更新所返回的行数中可以看出并非所有的行都得到处理。ROWCOUNT 影响所有的 Transact-SQL 语句。

  USE pubs
  GO
  SELECT count(*) AS Cnt
  FROM titles 
  WHERE advance >= 5000
  GO

  下面是结果集:

  Cnt       
  ----------- 
  11          

  (1 row(s) affected)

  现在,将 ROWCOUNT 设置为 4,并更新预付款等于或大于 $5,000 的所有行。

  -- SET ROWCOUNT to 4.
  SET ROWCOUNT 4
  GO
  UPDATE titles
  SET advance = 5000
  WHERE advance >= 5000
  GO

  9. SET TRANSACTION ISOLATION LEVEL
  说明:控制由连接发出的所有 Microsoft® SQL Server™ SELECT 语句的默认事务锁定行为。

  语法:SET TRANSACTION ISOLATION LEVEL
  { READ COMMITTED
      | READ UNCOMMITTED
      | REPEATABLE READ
      | SERIALIZABLE 
  }

  参数:READ COMMITTED 指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是 SQL Server 的默认值。
  READ UNCOMMITTED 执行脏读或 0 级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。
  REPEATABLE READ 锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。
  SERIALIZABLE 在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有 SELECT 语句中的所有表上设置 HOLDLOCK 相同。

  注释:一次只能设置这些选项中的一个,而且设置的选项将一直对那个连接保持有效,直到显式更改该选项为止。这是默认行为,除非在语句的 FROM 子句中在表级上指定优化选项。
  SET TRANSACTION ISOLATION LEVEL 的设置是在执行或运行时设置,而不是在分析时设置。

  示例:下例为会话设置 TRANSACTION ISOLATION LEVEL。对于每个后续 Transact-SQL 语句,SQL Server 将所有共享锁一直控制到事务结束为止。

  SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
  GO
  BEGIN TRANSACTION
  SELECT * FROM publishers
  SELECT * FROM authors
  ...
  COMMIT TRANSACTION

  10. SET XACT_ABORT

  说明:指定当 Transact-SQL 语句产生运行时错误时,Microsoft® SQL Server™ 是否自动回滚当前事务。

  语法:SET XACT_ABORT { ON | OFF }

  注释:当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为 OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。编译错误(如语法错误)不受 SET XACT_ABORT 的影响。
  对于大多数 OLE DB 提供程序(包括 SQL Server),隐性或显式事务中的数据修改语句必须将 XACT_ABORT 设置为 ON。唯一不需要该选项的情况是提供程序支持嵌套事务时。有关更多信息,请参见分布式查询和分布式事务。 
  SET XACT_ABORT 的设置是在执行或运行时设置,而不是在分析时设置。

  示例:下例导致在含有其它 Transact-SQL 语句的事务中发生违反外键错误。在第一个语句集中产生错误,但其它语句均成功执行且事务成功提交。在第二个语句集中,SET XACT_ABORT 设置为 ON。这导致语句错误使批处理终止,并使事务回滚。 

  CREATE TABLE t1 (a int PRIMARY KEY)
  CREATE TABLE t2 (a int REFERENCES t1(a))
  GO
  INSERT INTO t1 VALUES (1)
  INSERT INTO t1 VALUES (3)
  INSERT INTO t1 VALUES (4)
  INSERT INTO t1 VALUES (6)
  GO
  SET XACT_ABORT OFF
  GO
  BEGIN TRAN
  INSERT INTO t2 VALUES (1)
  INSERT INTO t2 VALUES (2) /* Foreign key error */
  INSERT INTO t2 VALUES (3)
  COMMIT TRAN
  GO

  SET XACT_ABORT ON
  GO

  BEGIN TRAN
  INSERT INTO t2 VALUES (4)
  INSERT INTO t2 VALUES (5) /* Foreign key error */
  INSERT INTO t2 VALUES (6)
  COMMIT TRAN
  GO

  /* Select shows only keys 1 and 3 added. 
     Key 2 insert failed and was rolled back, but
     XACT_ABORT was OFF and rest of transaction
     succeeded.
     Key 5 insert error with XACT_ABORT ON caused

<think>好的,我现在要帮用户解决在Kettle的Job中调用SQL存储过程并将结果循环返回到转换中的变量这个问题。首先,我需要回忆一下Kettle的基本结构和组件。Kettle有Job和Transformation两种类型的文件,Job用来控制流程,Transformation处理数据。用户的需求涉及到存储过程、循环和变量传递,这可能需要结合多个组件来实现。 根据引用内容,用户提到过使用“表输入”、“设置变量”、“复制记录到结果”等组件,还有在循环Job中勾选“对每个输入行执行一次”。这可能意味着需要从存储过程获取结果集,然后逐行处理,将每行的值设置为变量,传递给后续的转换。 首先,调用存储过程通常可以通过“执行SQL脚本”组件或者在“表输入”中使用CALL语句。不过存储过程如果有结果集返回的话,可能需要用“表输入”来获取。接下来,可能需要将结果集中的每一行记录传递到后续的转换中,这候需要用到“复制记录到结果”组件,然后在转换开始用“从结果获取记录”来接收数据。 然后,在循环处理每一行,需要设置变量,这里可能要用到设置变量”组件。同,在Job中调用转换,需要确保变量能够传递过去,可能需要在Job的“转换”步骤中勾选“将结果行复制到参数”和“将参数传递到子转换”。 用户的问题中还提到要将结果循环返回到转换中的变量,这可能需要一个父Job和一个子转换。父Job负责调用存储过程并循环结果,子转换则使用这些变量进行后续处理。需要注意变量作用域的问题,可能需要将变量设置为父Job的变量,或者通过参数传递到子转换。 另外,引用中提到在循环Job中勾选“对每个输入行都执行一次”,这样才能处理每一条记录。所以在设置Job,必须确保这个选项被勾选,以便每条记录都会触发一次子转换的执行,同传递相应的变量值。 可能的步骤包括: 1. 在Job中使用“表输入”执行存储过程,获取结果集。 2. 使用“复制记录到结果”将结果集传递到后续步骤。 3. 在循环中,通过“设置变量”组件将当前行的字段值设置为变量。 4. 调用子转换,并在调用传递这些变量。 5. 子转换中使用“获取变量”来接收并使用这些变量值。 还需要注意变量的命名和大小写,Kettle中变量通常是区分大小写的。同,存储过程的调用语法是否正确,例如在MySQL使用CALL procedure_name(),而在其他数据库如SQL Server可能使用EXEC等。 可能遇到的问题包括:存储过程返回多个结果集如何处理,变量是否正确传递,循环是否按预期工作。需要检查每个组件的配置,尤其是字段名称和变量名称是否匹配,以及是否在正确的作用域内设置了变量。 最后,根据引用中的示例,可能需要参考如何设置变量和循环,比如引用3提到的“设置变量”和“从结果获取记录”组件的使用,以及循环Job的配置。结合这些信息,可以构建一个示例流程,逐步演示如何实现用户的需求。</think>在Kettle中实现调用存储过程并循环返回结果至转换变量,需结合Job和Transformation的协同操作。以下是具体实现步骤: --- ### **一、Job设计流程** 1. **执行存储过程获取结果集** ```sql -- 在"表输入"步骤中使用CALL语句调用存储过程 CALL your_procedure_name('${input_param}'); ``` 通过`表输入`组件执行存储过程并获取结果集,需在数据库连接配置中启用存储过程调用支持[^3]。 2. **复制结果集到内存** - 添加`复制记录到结果`组件,将存储过程返回的结果集暂存至内存缓冲区[^3]。 3. **循环处理每一行数据** - 使用`设置变量`组件逐行提取字段值,例如: ```javascript // 在JavaScript代码中设置变量 setVariable("OUTPUT_VAR", output_field, "r"); ``` 或直接通过`Select values`组件映射字段并传递至下游[^3]。 4. **调用子转换并传递参数** - 在Job的`转换`步骤中勾选以下选项: - **替换SQL语句中的变量** - **将结果行复制到参数** - **将参数传递到子转换**[^1] --- ### **二、子转换设计流程** 1. **接收父Job传递的变量** - 使用`获取变量`组件读取父Job设置的变量值,例如:$**{OUTPUT_VAR}** 2. **使用变量进行后续操作** ```sql -- 在子转换的"表输入"中引用变量 SELECT * FROM target_table WHERE filter_column = '${OUTPUT_VAR}'; ``` --- ### **三、完整示例代码** ```xml <!-- Job示例片段 --> <step> <name>Execute Stored Procedure</name> <type>TableInput</type> <sql>CALL your_procedure('${param}');</sql> </step> <step> <name>Copy Rows to Result</name> <type>CopyRowsToResult</type> </step> <step> <name>Loop Through Rows</name> <type>Trans</type> <pass_all_rows>true</pass_all_rows> <params> <param>OUTPUT_VAR</param> </params> </step> <!-- 子转换示例 --> <step> <name>Use Variable in Transformation</name> <type>TableOutput</type> <sql>INSERT INTO result_table VALUES ('${OUTPUT_VAR}');</sql> </step> ``` --- ### **四、注意事项** 1. **变量作用域**:Job级变量需通过`设置变量`显式声明,转换中通过`${VAR}`引用[^3]。 2. **结果集分页**:若存储过程返回大数据集,需在`表输入`中配置分页参数避免内存溢出。 3. **错误处理**:添加`检验字段值`步骤验证变量有效性,防止空值导致流程中断[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值