【问题标题】:Copy big procedure between schemas在模式之间复制大过程
【发布时间】:2019-08-29 18:37:50
【问题描述】:

我有一个模式,我在其中定义了过程。此过程可以修改,并且应该在所有租户之间复制(我们有基于模式的租户)。主要思想是拥有某种模板化的过程,这些过程将在过程被修改后通过其他租户的模式自动更新。 为了写这个“复制”过程,我写了这样的东西:

DECLARE 
    @proc_name NVARCHAR(150) = 'ProcedureToCopy',
    @proc_sql NVARCHAR(MAX),
    @schema_name NVARCHAR(MAX) = 'test';

SELECT 
    @proc_sql = REPLACE(ROUTINE_DEFINITION, '[templates].', '['+@schema_name+'].')
FROM
    INFORMATION_SCHEMA.ROUTINES 
WHERE
    ROUTINE_TYPE='PROCEDURE' AND
    ROUTINE_NAME = @proc_name AND
    ROUTINE_SCHEMA = 'templates'

PRINT(@proc_sql);

EXEC(@proc_sql);

但是我遇到了大程序(超过 17k 个符号)的问题。无法复制,因为NVARCHAR(MAX) 限制为 4k 符号,所以我的@proc_sql 被修剪并且不包含所有必需的过程定义。

任何人都可以建议我的问题的解决方案或其他方法吗?

【问题讨论】:

标签: sql-server tsql stored-procedures


【解决方案1】:

您应该可以使用它来代替 INFORMATION_SCHEMA.ROUTINES。

SELECT o.name, definition, LEN(definition), o.type_desc 
FROM sys.sql_modules m 
INNER JOIN sys.objects o 
    ON m.object_id = o.object_id

用你的例子:

DECLARE @proc_name NVARCHAR(150) = 'doSomething',
    @proc_sql NVARCHAR(MAX),
    @schema_name NVARCHAR(MAX) = 'dbo';

SELECT  @proc_sql = REPLACE(m.definition, '[templates].', '[' + @schema_name + '].')
--select *
FROM    sys.sql_modules m
    INNER JOIN sys.objects o
        ON m.object_id = o.object_id
WHERE
    o.type_desc = 'sql_stored_Procedure'
    AND o.name = @proc_name
    AND SCHEMA_NAME(o.schema_id) = @schema_name

PRINT (@proc_sql);

EXEC (@proc_sql);

【讨论】:

  • 是的!它做了一个伎俩!想知道 INFORMATION_SCHEMA 和 sys.sql_modules 有什么区别...
  • 我不知道具体,但我过去曾遇到过这个问题。 INFORMATION_SCHEMA 对象只是针对原始表的视图。您可以通过运行以下命令查看源代码:EXEC sp_helptext 'information_Schema.routines'
【解决方案2】:

问题不在于NVARCHAR(MAX)NVARCHAR(MAX) 将允许最多 2GB 的信息。这可能比任何开发人员编写的代码都多。

问题在于INFORMATION_SCHEMA 视图仅限于NVARCHAR(4000),这就是截断发生的地方。您应该尝试对所有重要查询使用系统视图。

DECLARE 
    @proc_name nvarchar(150) = 'ProcedureToCopy',
    @proc_sql nvarchar(MAX),
    @schema_name nvarchar(MAX) = 'test';

SELECT @proc_sql = REPLACE(m.definition, N'[templates].', QUOTENAME( @schema_name)+N'.')
FROM sys.sql_modules m
JOIN sys.objects o ON m.object_id = o.object_id
JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE
    o.type_desc = 'SQL_STORED_PROCEDURE' AND
    o.name = @proc_name AND
    s.name = 'templates';

--PRINT(@proc_sql);

EXECUTE sp_executesql @proc_sql;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    相关资源
    最近更新 更多