【问题标题】:Creation of stored procedures in SQL Server在 SQL Server 中创建存储过程
【发布时间】:2017-08-08 19:32:27
【问题描述】:

我正在开发一个相当大的应用程序,其中通过运行 SQL 脚本来创建数据库模式(表、存储过程等)。该脚本是通过 xp_cmdshell 从存储过程中调用的,如下所示。

CREATE PROC CreateNewScheme AS
BEGIN
    ...
    EXEC xp_cmdshell 'osql createschema.sql -U username ...'
    ...
END

此存储过程在程序初始化期间运行一次,并在计划作业期间由 SQL Server 代理再次运行。

出于安全考虑,我们需要禁用 xp_cmdshell。我的第一个倾向是将所有模式创建命令插入现有的存储过程,以便可以根据需要执行。但是,这种方法不起作用,因为 SQL Server 不支持从其他存储过程创建存储过程。

一种替代方法可能是从外部应用程序而不是 SQL 脚本调用架构创建脚本,但这需要相当大的重写,我们会尽可能避免这种情况。

有没有一种方法可以通过最少的更改来实现这一点?

【问题讨论】:

    标签: sql-server stored-procedures sql-server-2016 xp-cmdshell


    【解决方案1】:

    我的第一个倾向是将所有模式创建命令插入现有存储过程,以便可以根据需要执行。 但是,这种方法不起作用,因为 SQL Server 不支持从其他存储过程创建存储过程。

    如果您确实需要将存储过程的创建包装在另一个存储过程中,您可以使用动态 SQL 包装它:

    CREATE PROC CreateNewScheme AS
    BEGIN
        EXEC('CREATE PROCEDURE myfirstproc AS ...');
    
        EXEC('CREATE PROCEDURE mysecondproc AS ...');
    END
    

    当然,您必须在动态 SQL 中转义每个 '


    另一种方法是直接从 SQL Server 代理作业执行 osql:

    您应该检查 SQL Server 代理帐户是否有足够的权限或创建代理。

    编辑:

    如果您无法使用 SQL Server 代理,请使用 Windows 任务计划程序运行 osql:

    【讨论】:

    • 动态 SQL 方法似乎有点混乱,因为我必须包装 100 多个存储过程,其中一些相当复杂。这将是耗时且容易出错的。不过我喜欢使用 SQL Server 代理的想法。
    • 根据微软的说法,有一种方法可以直接从 q SQL 脚本执行 SQL Server 代理作业。这可能是一个很好的解决方案,因为有一种方法可以等待作业完成后再继续。
    • 事实证明,使用 SQL Server 代理也不是一个可行的选择,因为它提供了对命令行的访问。因此,它被认为是一个安全漏洞,将被关闭。
    • @MikeCollins Windows 任务计划程序怎么样?它独立于 SQL Server,是操作系统的一部分。
    【解决方案2】:

    我们的情况和你一样,我们想禁用xp_cmdshell,我们在生产服务器上用于几件事。

    我们所做的是为xp_cmdshell 在我们的环境中执行的操作创建SQLCLR 方法。当然,程序集必须创建为UNSAFE,但方法只能为单个操作调用,并且方法有很多验证代码,所以我们没有做任何“愚蠢”的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-24
      • 2013-05-02
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      相关资源
      最近更新 更多