我的表中有一个值被意外更改。有问题的列是
CreatedDate
,它是在创建我的项目时设置的,但它正在被存储过程更改。
我可以编写某种类型的
SELECT
语句来获取表中引用此列的所有过程名称吗?
一个选项是创建脚本文件。
右键单击数据库->任务->生成脚本
然后您可以选择所有存储过程并生成包含所有 sps 的脚本。所以你可以从那里找到参考。
或者
-- Search in All Objects
SELECT OBJECT_NAME(OBJECT_ID),
definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'CreatedDate' + '%'
GO
-- Search in Stored Procedure Only
SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
object_definition(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'CreatedDate' + '%'
GO
如果您只想获取仅使用特定列的存储过程,您可以使用尝试以下查询:
SELECT DISTINCT Name
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%CreatedDate%';
如果您想使用表的特定列获取存储过程,您可以使用以下查询:
SELECT DISTINCT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%tbl_name%'
AND OBJECT_DEFINITION(OBJECT_ID) LIKE '%CreatedDate%';
您可以使用ApexSQL Search,它是一个免费的 SSMS 和 Visual Studio 插件,它可以列出引用特定表列的所有对象。它还可以查找存储在表和视图中的数据。您可以轻松过滤结果以显示引用该列的特定数据库对象类型
免责声明:我在 ApexSQL 担任支持工程师
您可以使用 information_schema
中包含的系统视图通过一个脚本来在表、视图和(未加密)存储过程中进行搜索。前段时间我开发了这样一个脚本,因为我需要在数据库中到处搜索字段名称。
下面的脚本首先列出包含您要搜索的列名称的表/视图,然后列出找到该列的存储过程源代码。它在一个表中显示结果,区分“BASE TABLE”、“VIEW”和“PROCEDURE”,并(可选)在第二个表中显示源代码:
DECLARE @SearchFor nvarchar(max)='%CustomerID%' -- search for this string
DECLARE @SearchSP bit = 1 -- 1=search in SPs as well
DECLARE @DisplaySPSource bit = 1 -- 1=display SP source code
-- tables
if (@SearchSP=1) begin
(
select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object],
t.table_type
from information_schema.columns c
left join information_schema.Tables t on c.table_name=t.table_name
where column_name like @SearchFor
union
select '['+routine_Schema+'].['+routine_Name+']' [schema_object],
'PROCEDURE' as table_type from information_schema.routines
where routine_definition like @SearchFor
and routine_type='procedure'
)
order by table_type, schema_object
end else begin
select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object],
t.table_type
from information_schema.columns c
left join information_schema.Tables t on c.table_name=t.table_name
where column_name like @SearchFor
order by c.table_Name, c.column_name
end
-- stored procedure (source listing)
if (@SearchSP=1) begin
if (@DisplaySPSource=1) begin
select '['+routine_Schema+'].['+routine_Name+']' [schema.sp], routine_definition
from information_schema.routines
where routine_definition like @SearchFor
and routine_type='procedure'
order by routine_name
end
end
如果运行查询,请使用“结果作为文本”选项 - 然后您可以使用“查找”在结果集中定位搜索文本(对于长源代码很有用)。
注意,如果您只想显示 SP 名称,则可以将
@DisplaySPSource
设置为 0
,如果您只是查找表/视图,而不是 SP,则可以将 @SearchSP
设置为 0
。
结果示例(在 Northwind 数据库中查找
CustomerID
,结果通过 LinqPad 显示):
注意我已使用测试视图验证了此脚本
dbo.TestOrders
即使在 CustomerID
语句中使用了 c.*
,它仍在此视图中找到 SELECT
(引用表 Customers
包含 CustomerID
,因此视图显示此列)。
LinqPad 用户注意:在 C# 中, 您可以使用
dc.ExecuteQueryDynamic(sqlQueryStr, new object[] {... parameters ...} ).Dump();
并在查询字符串中将参数设置为 @p0
... @pn
。然后,您可以编写一个静态扩展类并将其保存在My Extensions下,以便在 LinqPad 查询中使用。数据上下文可以通过参数作为 DataContextBase dc
从查询窗口传递,即公共静态扩展类中的 public static void SearchDialog(this DataContextBase dc, string searchString = "%")
(在 LinqPad 6 中,它是 DataContext
)。然后,您可以将上面的 SQL 查询重写为带参数的字符串,并从 C# 上下文中调用它。
试试这个..
SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%CreatedDate%'
GO
或者您可以生成所有过程的脚本并从那里进行搜索。
我有同样的问题,我发现Microsoft有一个systable显示依赖关系。
SELECT
referenced_id
, referenced_entity_name AS table_name
, referenced_minor_name as column_name
, is_all_columns_found
FROM sys.dm_sql_referenced_entities ('dbo.Proc1', 'OBJECT');
这适用于
Views
和 Triggers
。
-- 在所有对象中搜索
SELECT OBJECT_NAME(OBJECT_ID),
definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'ColumnName' + '%'
GO
-- 仅在存储过程中搜索
SELECT DISTINCT OBJECT_NAME(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'ColumnName' + '%'
GO
SELECT *
FROM sys.all_sql_modules
WHERE definition LIKE '%CreatedDate%'
您可以使用以下查询来识别这些值。但请记住,这不会为您提供加密存储过程的结果。
SELECT DISTINCT OBJECT_NAME(comments.id) OBJECT_NAME
,objects.type_desc
FROM syscomments comments
,sys.objects objects
WHERE comments.id = objects.object_id
AND TEXT LIKE '%CreatedDate%'
ORDER BY 1