Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查询以根据列查找存储过程_Sql_Sql Server_Sql Server 2008_Stored Procedures - Fatal编程技术网

Sql 查询以根据列查找存储过程

Sql 查询以根据列查找存储过程,sql,sql-server,sql-server-2008,stored-procedures,Sql,Sql Server,Sql Server 2008,Stored Procedures,我必须更改表列的名称和数据类型。我在数据库中有大约150个存储过程,其中大约25个引用了同一列。我需要一个查询,可以找到依赖于此列的所有存储过程的名称。我使用此查询: SELECT OBJECT_NAME(M.object_id), M.* FROM sys.sql_modules M JOIN sys.procedures P ON M.object_id = P.object_id WHERE M.definition LIKE '%blah%' 显然,你必须用“blah”来代替你的专栏名

我必须更改表列的名称和数据类型。我在数据库中有大约150个存储过程,其中大约25个引用了同一列。我需要一个查询,可以找到依赖于此列的所有存储过程的名称。

我使用此查询:

SELECT OBJECT_NAME(M.object_id), M.*
FROM sys.sql_modules M
JOIN sys.procedures P
ON M.object_id = P.object_id
WHERE M.definition LIKE '%blah%'
显然,你必须用“blah”来代替你的专栏名称

我使用这个查询:

SELECT OBJECT_NAME(M.object_id), M.*
FROM sys.sql_modules M
JOIN sys.procedures P
ON M.object_id = P.object_id
WHERE M.definition LIKE '%blah%'
显然,你必须用“blah”来代替你的专栏名称

试试这个1 来自Sp

从桌子上

SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%EmployeeID%'
ORDER BY schema_name, table_name;
试试这个1 来自Sp

从桌子上

SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%EmployeeID%'
ORDER BY schema_name, table_name;

问题:

正如您所知,无法查询函数或存储过程引用了哪些字段。
我们能得到的最接近值是近似值。
我们可以知道哪些表被引用,哪些字段可能被这些表引用。

例如,如果“Person”表引用了“CreatedDate”,并且您加入了“Order”表(该表也有一个“CreatedDate”字段),那么当您只查找“Person.CreatedDate”时,它将发现与“Order.CreatedDate”匹配的“假阳性”。

不幸的是,目前我们只能在对象脚本的文本中搜索字段名。
好消息是,它不会错过识别实际使用的字段。
如果有任何问题,它可能会拉入比使用的更多的内容(由于共享字段名或注释掉的代码)。
唯一的例外是动态SQL,因为如果表嵌入到动态字符串中,则它们不会链接到对象脚本。

解决方法:

CREATE FUNCTION [dbo].[ft_Schema_Column_Script]
(
    @ScriptName nVarChar(128) = '%',
    @TableName  nVarChar(128) = '%',
    @ColumnName nVarChar(128) = '%'
)
RETURNS TABLE
AS
RETURN
(
    SELECT @@SERVERNAME[ServerName], DB_NAME()[DatabaseName],
           SS.name[ScriptSchemaName], SO.name[ScriptName],
           SO.type_desc[ScriptType], 
           TS.name[TableSchemaName], T.name[TableName], C.name[ColumnName],
           UT.name[ColumnType], C.max_length[MaxLength],
           C.precision[NumericPrecision], C.scale[Scale],
           C.is_nullable[Nullable],
           C.is_identity[IsIdentity],
           C.column_id[Ordinal],
           EP.value[Description]
      FROM sys.sql_modules as M
      JOIN sys.objects     as SO--Script Object.
        ON M.object_id = SO.object_id
      JOIN sys.schemas as SS--Script Schema.
        ON SS.schema_id = SO.schema_id
      JOIN sys.sql_expression_dependencies D
        ON D.referencing_id = SO.object_id
      JOIN sys.tables as T
        ON T.object_id = D.referenced_id
      JOIN sys.schemas as TS--Table Schema.
        ON TS.schema_id = T.schema_id
      JOIN sys.columns as C
        ON C.object_id = T.object_id
      LEFT JOIN sys.types AS UT--Left Join because of user-defined/newer types.
        ON UT.user_type_id = C.user_type_id
      LEFT JOIN sys.extended_properties AS EP
        ON EP.major_id = C.object_id
       AND EP.minor_id = C.column_id
       AND EP.name = 'MS_Description'
     WHERE  T.name LIKE @TableName  ESCAPE '\'
       AND  C.name LIKE @ColumnName ESCAPE '\'
       AND SO.name LIKE @ScriptName ESCAPE '\'
       --Use RegEx to exclude false-posotives by from similar ColumnNames.
       --  (e.g. Ignore the "ModifiedBy" field when matching on "Modified").
       --  Use C.name instead of @ColumnName to further reduce false-positives.
       AND M.definition LIKE (  N'%[ ~`!@#$\%\^&*()+-=\[\]\\{}|;'''':",./<>?]'
                              + C.name
                              + N'[ ~`!@#$\%\^&*()+-=\[\]\\{}|;'''':",./<>?]%'
                             ) ESCAPE '\'
)
GO
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
   SELECT * FROM dbo.ft_Schema_Column_Script('ScriptName', DEFAULT, DEFAULT) as C
   SELECT * FROM dbo.ft_Schema_Column_Script(DEFAULT, 'TableName',  DEFAULT) as C
   SELECT * FROM dbo.ft_Schema_Column_Script(DEFAULT, DEFAULT, 'ColumnName') as C
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
测试上面的示例,看看它是否足以满足您的需要。

结果:

运行此函数搜索列名“已创建”时的输出示例。


它搜索存储过程(存储过程)、用户定义函数(UDF)、触发器,但不搜索作业。

最酷的是:

这不仅搜索脚本引用的列,
还搜索列(或表)引用的脚本

问题:

正如您所知,无法查询函数或存储过程引用了哪些字段。
我们能得到的最接近值是近似值。
我们可以知道哪些表被引用,哪些字段可能被这些表引用。

例如,如果“Person”表引用了“CreatedDate”,并且您加入了“Order”表(该表也有一个“CreatedDate”字段),那么当您只查找“Person.CreatedDate”时,它将发现与“Order.CreatedDate”匹配的“假阳性”。

不幸的是,目前我们只能在对象脚本的文本中搜索字段名。
好消息是,它不会错过识别实际使用的字段。
如果有任何问题,它可能会拉入比使用的更多的内容(由于共享字段名或注释掉的代码)。
唯一的例外是动态SQL,因为如果表嵌入到动态字符串中,则它们不会链接到对象脚本。

解决方法:

CREATE FUNCTION [dbo].[ft_Schema_Column_Script]
(
    @ScriptName nVarChar(128) = '%',
    @TableName  nVarChar(128) = '%',
    @ColumnName nVarChar(128) = '%'
)
RETURNS TABLE
AS
RETURN
(
    SELECT @@SERVERNAME[ServerName], DB_NAME()[DatabaseName],
           SS.name[ScriptSchemaName], SO.name[ScriptName],
           SO.type_desc[ScriptType], 
           TS.name[TableSchemaName], T.name[TableName], C.name[ColumnName],
           UT.name[ColumnType], C.max_length[MaxLength],
           C.precision[NumericPrecision], C.scale[Scale],
           C.is_nullable[Nullable],
           C.is_identity[IsIdentity],
           C.column_id[Ordinal],
           EP.value[Description]
      FROM sys.sql_modules as M
      JOIN sys.objects     as SO--Script Object.
        ON M.object_id = SO.object_id
      JOIN sys.schemas as SS--Script Schema.
        ON SS.schema_id = SO.schema_id
      JOIN sys.sql_expression_dependencies D
        ON D.referencing_id = SO.object_id
      JOIN sys.tables as T
        ON T.object_id = D.referenced_id
      JOIN sys.schemas as TS--Table Schema.
        ON TS.schema_id = T.schema_id
      JOIN sys.columns as C
        ON C.object_id = T.object_id
      LEFT JOIN sys.types AS UT--Left Join because of user-defined/newer types.
        ON UT.user_type_id = C.user_type_id
      LEFT JOIN sys.extended_properties AS EP
        ON EP.major_id = C.object_id
       AND EP.minor_id = C.column_id
       AND EP.name = 'MS_Description'
     WHERE  T.name LIKE @TableName  ESCAPE '\'
       AND  C.name LIKE @ColumnName ESCAPE '\'
       AND SO.name LIKE @ScriptName ESCAPE '\'
       --Use RegEx to exclude false-posotives by from similar ColumnNames.
       --  (e.g. Ignore the "ModifiedBy" field when matching on "Modified").
       --  Use C.name instead of @ColumnName to further reduce false-positives.
       AND M.definition LIKE (  N'%[ ~`!@#$\%\^&*()+-=\[\]\\{}|;'''':",./<>?]'
                              + C.name
                              + N'[ ~`!@#$\%\^&*()+-=\[\]\\{}|;'''':",./<>?]%'
                             ) ESCAPE '\'
)
GO
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
   SELECT * FROM dbo.ft_Schema_Column_Script('ScriptName', DEFAULT, DEFAULT) as C
   SELECT * FROM dbo.ft_Schema_Column_Script(DEFAULT, 'TableName',  DEFAULT) as C
   SELECT * FROM dbo.ft_Schema_Column_Script(DEFAULT, DEFAULT, 'ColumnName') as C
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
测试上面的示例,看看它是否足以满足您的需要。

结果:

运行此函数搜索列名“已创建”时的输出示例。


它搜索存储过程(存储过程)、用户定义函数(UDF)、触发器,但不搜索作业。

最酷的是:

这不仅搜索脚本引用的列,
还搜索列(或表)引用的脚本

仅在存储过程中搜索:

SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
object_definition(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'BusinessEntityID' + '%'

仅在存储过程中搜索:

SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
object_definition(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'BusinessEntityID' + '%'
--搜索所有对象

选择对象名称(对象ID), 释义 从sys.sql\u模块 其中定义“%”+“BusinessEntityID“+”%”

--在所有对象中搜索

选择对象名称(对象ID), 释义 从sys.sql\u模块
如果定义为“%”+“BusinessEntityID”+“%”

您还需要检查是否有任何视图正在使用该列,并包括依赖于这些视图的存储过程的列表。然后,您还应该检查哪些存储过程依赖于此存储过程列表,哪些存储过程依赖于这些存储过程,等等。通常,调用链的深度不会超过2-3级,因此这应该不会太难。请注意,这只确定哪些过程包含字符串“blah”-它们不一定引用您的列。不过,这是没有第三方工具的最佳开端。这个查询中的问题是,它不包括表名。我有多个具有相同列名称的表。如果添加“和“%blahtable%”之类的M.definition条件,则只会筛选包含这两个术语的存储过程。如果可以保证定义的两个列名后跟表名(从blahtable中选择blah),则可以将条件更改为“像“%blah%blahtable%”“等等……注释可能是个问题,您还需要检查是否有任何视图正在使用该列,并包括依赖于这些视图的存储过程的列表。然后,您还应该检查哪些存储过程依赖于此存储过程列表,哪些存储过程依赖于这些存储过程,等等。通常,调用链的深度不会超过2-3级,因此这应该不会太难。请注意,这只确定哪些过程包含字符串“blah”-它们不一定引用您的列。不过,这是没有第三方工具的最佳开端。这个查询中的问题是,它不包括表名。我有多个具有相同列名称的表。如果添加“和“%blahtable%”之类的条件和M.definition,则只会筛选包含这两个术语的存储过程。如果可以保证定义的两个列名后跟表名(从blahtable中选择blah),则可以更改条件t