EXEC sp_rename 在 while 循环中执行几次后停止

EXEC sp_rename stop after several times in a while loop

我尝试用 table 的第一行重命名我的列名。 (我知道,它在 SQL 中没有意义 'a first row without order by',但我必须为我的测试这样做)。 所以,我不想动态搜索我的旧列名和新列名以在 while 循环中执行 sp_rename 。 这是ma代码:

DECLARE @i INT;
SET @i = 0;
DECLARE @oldnom NVARCHAR(MAX);
DECLARE @newnom NVARCHAR(MAX)  
DECLARE @sSQL NVARCHAR(MAX);
DECLARE @ParmDefinition NVARCHAR(MAX);
DECLARE @tablename NVARCHAR(MAX) ;
SET @tablename = N'Produit_A';
WHILE @i < (SELECT MAX(rownum) FROM (SELECT ROW_NUMBER() OVER(ORDER BY ORDINAL_POSITION ASC) AS rownum,COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tablename AND COLUMN_NAME like 'Prop%') truc)
BEGIN
    SET @oldnom = 'Prop_'+CAST(@i AS NVARCHAR(MAX))
    SET @oldnom = 'dbo.'+@tablename+'.['+@oldnom+']'
    SET @i = @i + 1
    SELECT @sSQL = N'SELECT TOP 1 @retvalOUT = COALESCE('+@oldnom+','''+@oldnom+''') FROM dbo.' + @tablename;
    SET @ParmDefinition = N'@retvalOUT NVARCHAR(MAX) OUTPUT';
    EXEC sp_executesql @sSQL, @ParmDefinition, @retvalOUT=@newnom OUTPUT;
    IF @newnom <> @oldnom
    BEGIN
        SELECT @oldnom, @newnom;
--      EXEC sp_rename @oldnom, @newnom;
    END
END

我的请求工作正常,SELECT @oldnom,@newnom; return 所有需要重命名的列,并且可以使我的 sp_rename.

然而,当我取消注释 EXEC sp_rename @oldnom, @newnom;并执行我的请求。

我的专栏重命名很好,但不是全部。我的 exec 在一定数量后无错误地停止。

如果我改变了 while 的开始,以下列也被很好地重命名,所以问题不是由于某个列的错误。

我不明白为什么 select 工作正常但 exec sp_rename 几次后停止工作...

我考虑过单个请求的执行限制,但找不到任何相关信息。

我还考虑了 return 由 sp_rename 命令编辑的错误消息(注意:更改对象名称的任何部分可能会破坏脚本和存储过程。),但同样,没有信息.

您没有向我们提供第一行的列名,所以我们不得不失明。

但基于它在您不重命名时有效的事实,我敢打赌问题出在您的查询中:

@i < select max(rownum) from (.....)truc

请注意,此查询在 次迭代后计算。当您不重命名列时效果很好,因为每次 returns 都是一样的。

但是如果您确实重命名了列,您将从此查询中删除行,因为:

AND COLUMN_NAME like 'Prop%'

这会导致您的查询每隔一列“跳转”一次。示例:

第一次迭代,row_number=1,列重命名为 [SomeColumn1Title]。

第二次迭代。第一行不再是 [SomeColumn1Title],而是 [SomeColumn2Title]。然而,你在@i=2,所以会发生的是第 3 列将被重命名。等等。

这段代码真的很不稳定。只需使用游标,它只会对您的查询求值一次。

问题出在我的 while 循环条件中。 我将修复我的代码并使用游标来避免循环。 非常感谢 ! 这是我更正的代码:

DECLARE @tablename NVARCHAR(MAX);
DECLARE 
    @oldnom NVARCHAR(MAX), 
    @newnom NVARCHAR(MAX),
    @sSQL NVARCHAR(MAX),
    @ParmDefinition NVARCHAR(MAX),
    @requete NVARCHAR(MAX);
SET @tablename = N'Produit_A';
SET @requete = N'';
DECLARE cursor_col CURSOR FOR 
    SELECT name 
    FROM sys.columns 
    WHERE object_id = OBJECT_ID('bdd_canon.['+@tablename+']');
OPEN cursor_col;
FETCH NEXT FROM cursor_col INTO @oldnom ;
WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT @sSQL = N'SELECT TOP 1 @retvalOUT = COALESCE('+@oldnom+','''+@oldnom+''') FROM bdd_canon.' + @tablename;
        SET @ParmDefinition = N'@retvalOUT NVARCHAR(MAX) OUTPUT';
        EXEC sp_executesql @sSQL, @ParmDefinition, @retvalOUT=@newnom OUTPUT;
        IF @newnom <> @oldnom
        BEGIN
            SET @oldnom = '''bdd_canon.'+@tablename+'.['+@oldnom+']'''
            SET @newnom = ''''+@newnom+''''
            SET @requete = @requete + 'EXEC sp_rename '+@oldnom+', '+@newnom+',''COLUMN''; ';
        END
        FETCH NEXT FROM cursor_col INTO @oldnom ;
    END;
EXEC sp_executesql @requete
CLOSE cursor_col;
DEALLOCATE cursor_col;