首页 > 解决方案 > 哪个是首选 SELECT 或 SET

问题描述

分配变量时,set和select之间是否存在功能差异?

我经常编写必须遍历进程的脚本,并且在每次迭代时我都会用一个值更新一个变量。

例如,我公司的产品有多个服务器,在每台服务器上我们有一定数量的数据库,我们的客户数据驻留在其中。每个数据库有 5 到 50 个客户端。主数据库中的表指示每个客户端位于哪个单独的数据库中。今天发现一个表的主键有问题,我们需要修改主键添加一列。每个数据库上的表可能有几十万条记录,因此我们预计更新需要一些时间。我们需要在一夜之间完成这些以避免性能问题。所以我编写了以下脚本来遍历每个数据库上的进程(我将在每个服务器上分别执行它):

DECLARE @DBTABLE TABLE
(
    TableID                 INT IDENTITY PRIMARY KEY NOT NULL,
    DbName                  VARCHAR(50) NOT NULL,
    ServerName              VARCHAR(50) NOT NULL,
    ProcFlag                INT NOT NULL DEFAULT 0
)

INSERT INTO @DBTABLE (DbName, ServerName)
SELECT      DISTINCT DbName, ServerName
FROM        PrimaryDatabase.dbo.Cients WITH(NOLOCK)
WHERE       ClientInactive = 0
    AND     ServerName = @@SERVERNAME

DECLARE     @TABLETEST  INT
DECLARE     @TABLEID    INT
DECLARE     @DBNAME     VARCHAR(50)
DECLARE     @SERVERNAME VARCHAR(50)
DECLARE     @VAR_SQL    VARCHAR(MAX)

SET     @TABLETEST = (SELECT COUNT(*) FROM @DBTABLE WHERE ProcFlag = 0)
WHILE   @TABLETEST > 0
BEGIN
    SET     @TABLEID =      (SELECT MIN(TableID) FROM @DBTABLE WHERE ProcFlag = 0)
    SET     @DBNAME =       (SELECT DbName FROM @DBTABLE WHERE TableID = @TABLEID)
    SET     @SERVERNAME =   (SELECT ServerName FROM @DBTABLE WHERE TableID = @TABLEID)

    SET     @VAR_SQL = '

        ALTER TABLE ' + @DBNAME + '.dbo.ClientDealTable DROP CONSTRAINT [PK_ClientDealTable]
        ALTER TABLE ' + @DBNAME + '.dbo.ClientDealTable ADD CONSTRAINT [PK_ClientDealTable] PRIMARY KEY CLUSTERED ([ClientID] ASC, [DealNumber] ASC, [DealDate] ASC)
    '

    EXEC(@VAR_SQL)

    UPDATE      @DBTABLE SET ProcFlag = 1 WHERE TableID = @TABLEID
    SET         @TABLETEST = (SELECT COUNT(*) FROM @DBTABLE WHERE ProcFlag = 0)

END

是这里SET还是SELECT首选选项,还是真的很重要?有性能差异吗?

标签: sql-servertsql

解决方案


SET 只能设置单个变量的值。使用 SELECT 您可以设置任意数量的变量的值。

但在你的代码中我也不会使用。我会在不循环的情况下做到这一点。更不用说要编写的代码少之又少。这应该做同样的事情,而且要简单得多。

DECLARE @VAR_SQL VARCHAR(MAX)

SELECT @VAR_SQL = 'ALTER TABLE ' + QUOTENAME(DbName) + '.dbo.ClientDealTable DROP CONSTRAINT [PK_ClientDealTable];ALTER TABLE ' + QUOTENAME(DbName) + '.dbo.ClientDealTable ADD CONSTRAINT [PK_ClientDealTable] PRIMARY KEY CLUSTERED ([ClientID] ASC, [DealNumber] ASC, [DealDate] ASC)'
FROM PrimaryDatabase.dbo.Cients --WITH(NOLOCK)
WHERE ClientInactive = 0
    AND ServerName = @@SERVERNAME

exec sp_executesql @VAR_SQL

推荐阅读