Use a Query to access column description in SQL - sql

I am trying to access the Column description properties using the INFORMATION_SCHEMA
I have created this Query in the past to get the column name but i can not figure out how to get description of the column
SELECT COLUMN_NAME AS Output, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.COLUMNS
WHERE (TABLE_NAME = #Tablename) AND (ORDINAL_POSITION = #Location)
This is where the Description is on the field properties

If by 'description' you mean 'Description' displayed in SQL Management Studio in design mode, here it is:
select
st.name [Table],
sc.name [Column],
sep.value [Description]
from sys.tables st
inner join sys.columns sc on st.object_id = sc.object_id
left join sys.extended_properties sep on st.object_id = sep.major_id
and sc.column_id = sep.minor_id
and sep.name = 'MS_Description'
where st.name = #TableName
and sc.name = #ColumnName

If you specifically want to use INFORMATION_SCHEMA (as I was) then the following query should help you obtain the column's description field:
SELECT COLUMN_NAME AS [Output]
,ORDINAL_POSITION
,prop.value AS [COLUMN_DESCRIPTION]
FROM INFORMATION_SCHEMA.TABLES AS tbl
INNER JOIN INFORMATION_SCHEMA.COLUMNS AS col ON col.TABLE_NAME = tbl.TABLE_NAME
INNER JOIN sys.columns AS sc ON sc.object_id = object_id(tbl.table_schema + '.' + tbl.table_name)
AND sc.NAME = col.COLUMN_NAME
LEFT JOIN sys.extended_properties prop ON prop.major_id = sc.object_id
AND prop.minor_id = sc.column_id
AND prop.NAME = 'MS_Description'
WHERE tbl.TABLE_NAME = #TableName

The fn_listextendedproperty system function will do what you're looking for.
It’s also referred to as sys.fn_listextendedproperty.
Syntax is as follows:
fn_listextendedproperty (
{ default | 'property_name' | NULL }
, { default | 'level0_object_type' | NULL }
, { default | 'level0_object_name' | NULL }
, { default | 'level1_object_type' | NULL }
, { default | 'level1_object_name' | NULL }
, { default | 'level2_object_type' | NULL }
, { default | 'level2_object_name' | NULL }
)
Example Usage: Lists extended properties for all columns of the ScrapReason table in the Production schema
USE AdventureWorks2012;
GO
SELECT objtype, objname, name, value
FROM fn_listextendedproperty (NULL, 'schema', 'Production', 'table', 'ScrapReason', 'column', NULL);
GO
sp_helptext will not work since it can't be used for tables as per TechNet.
Displays the definition of a user-defined rule, default, unencrypted
Transact-SQL stored procedure, user-defined Transact-SQL function,
trigger, computed column, CHECK constraint, view, or system object
such as a system stored procedure.
sp_columns does not return the sys.extended_properties.value field which you're looking for.
fn_listextendedproperty is arguably easier to work with and more generic than the query in the accepted answer.

exec sp_columns #Tablename... That's the system stored procedure that will give you the info.
Other than that, here is a post with a lot of good information on the INFORMATION SCHEMA views: What is the equivalent of 'describe table' in SQL Server?

If you want to have table with table schema, table name, column name and description you can use following query:
select TableName = tbl.table_schema + '.' + tbl.table_name,
sc.name [Column],
sep.value [Description]
from sys.tables st
inner join information_schema.tables tbl on st.object_id=object_id(tbl.table_schema + '.' + tbl.table_name)
inner join sys.columns sc on st.object_id = sc.object_id
left join sys.extended_properties sep on st.object_id = sep.major_id
and sc.column_id = sep.minor_id
and sep.name = 'MS_Description'
This will generate follwing table:
Table name
Column name
Description
dbo.VersionInfo
AppliedOn
Description
I wanted to generate the md file in my CI/CD pipeline and for this purpose I created a PowerShell module. It has Out-Md switch which generates MD file with all descriptions.
Get-ColumnsDescription -Verbose -ServerInstance ".\SQL2019" -Database PTMeetings -OutMD
To cover topic completely:
If you would like to add the description with the query you can use
EXEC sys.sp_addextendedproperty
#name=N'MS_Description' --name of property
,#value=N'Age should be between 12 and 100 Descp' --descption text
,#level0type=N'SCHEMA'
,#level0name=N'jl' --Schema name
,#level1type=N'TABLE'
,#level1name=N'JournalItemNotes' --Table Name
,#level2type=N'COLUMN'
,#level2name=N'NotesType' -- Column Name
And if You are interested in the idempotent function I propose to create procedure:
IF OBJECT_ID ('dbo.usp_addorupdatedescription', 'P') IS NOT NULL
DROP PROCEDURE dbo.usp_addorupdatedescription;
GO
CREATE PROCEDURE usp_addorupdatedescription
#table nvarchar(128), -- table name
#column nvarchar(128), -- column name, NULL if description for table
#descr sql_variant -- description text
AS
BEGIN
SET NOCOUNT ON;
DECLARE #c nvarchar(128) = NULL;
IF #column IS NOT NULL
SET #c = N'COLUMN';
BEGIN TRY
EXECUTE sp_updateextendedproperty N'MS_Description', #descr, N'SCHEMA', N'dbo', N'TABLE', #table, #c, #column;
END TRY
BEGIN CATCH
EXECUTE sp_addextendedproperty N'MS_Description', #descr, N'SCHEMA', N'dbo', N'TABLE', #table, #c, #column;
END CATCH;
END
GO

Are you looking for the information in the sys.extended_properties view?
https://stackoverflow.com/a/15008885/1948904

Related

Retrieving which database(s) and tables contains a spesific column name within a multiple database soloution

I wish do retrieve the database which contains table x, based on a column name I enter through e.g. My WHERE statement.
As of now, I run two seperate SELECT queries. Firstly, I search for which tables in the soloution contains a spesific column.
Second, I have to manually search for all the resulting databases in the subquery.
I wish to have this dynamic, so that when entering the column name, both database and table are returned. Now, I get "NULL" the Database column.
I've managed to get the current db using only db_name, but that is not what I intend to do..
db_name(db_id(table1.name)) AS "Database" , table1.name AS 'Table', column1.name AS 'Column'
FROM sys.columns column1
JOIN sys.tables table1 ON column1.object_id = table1.object_id
WHERE column1.name LIKE 'columnname'
ORDER BY "Table", "Column"
(SELECT "db" FROM sys.databases WHERE CASE WHEN state_desc = 'ONLINE' THEN
OBJECT_ID(QUOTENAME("db") + '.[dbo].' + '[database1]', 'U')
END IS NOT NULL)
The code above is working wiithout errors. However, I do not manage to pull the Database name, and I can not understand how I could solve this.
I've used several earlier posts as reference to build up this code, as I'm a rookie to SQL.. :-)
Thanks in advance for any assitance.
Br.
This gives a bit more information than you requested, but it's a code that I had to create a data dictionary of my databases. You just need to change the value for the first variable to make it work.
--Change this value
DECLARE #ColumnName sysname = 'YourColumnName';
IF OBJECT_ID( 'tempdb..#DataDictionary') IS NOT NULL
DROP TABLE #DataDictionary;
CREATE TABLE #DataDictionary(
TABLE_CATALOG sysname,
TABLE_SCHEMA sysname,
TABLE_NAME sysname,
ORDINAL_POSITION int,
COLUMN_NAME sysname,
DATA_TYPE sysname,
IS_NULLABLE varchar(8)
);
DECLARE #SQL NVARCHAR(MAX);
DECLARE dbs CURSOR LOCAL FAST_FORWARD
FOR
SELECT REPLACE( 'USE <<database_name>>;
INSERT INTO #DataDictionary
SELECT DB_NAME() AS TABLE_CATALOG,
s.name AS TABLE_SCHEMA,
t.name AS TABLE_NAME,
COLUMNPROPERTY(c.object_id, c.name, ''ordinal'') AS ORDINAL_POSITION,
c.name AS COLUMN_NAME,
CASE WHEN ty.name IN (''char'', ''varchar'', ''varbinary'', ''binary'') THEN CONCAT( ty.name, ''('', ISNULL( CAST(NULLIF(c.max_length, -1) AS varchar(4)), ''MAX''), '')'')
WHEN ty.name IN (''nchar'', ''nvarchar'') THEN CONCAT( ty.name, ''('', ISNULL( CAST(NULLIF(c.max_length, -1)/2 AS varchar(4)), ''MAX''), '')'')
WHEN ty.name IN (''numeric'', ''decimal'') THEN CONCAT( ty.name, ''('', c.precision, '','', c.scale, '')'')
ELSE ty.name END AS DATA_TYPE,
IIF(c.is_nullable = 1, ''NULL'', ''NOT NULL'') AS IS_NULLABLE
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types ty ON c.user_type_id = ty.user_type_id
WHERE t.object_id NOT IN( SELECT major_id FROM sys.extended_properties WHERE minor_id = 0 AND class = 1 AND name = N''microsoft_database_tools_support'')
AND c.name = #ColumnName;', '<<database_name>>', name)
FROM sys.databases
WHERE database_id > 4 --No system databases
AND HAS_DBACCESS( name) = 1
AND state_desc = 'ONLINE'
OPEN dbs;
FETCH NEXT FROM dbs INTO #SQL;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC sp_executesql #SQL, N'#ColumnName sysname', #ColumnName;
FETCH NEXT FROM dbs INTO #SQL;
END;
CLOSE dbs;
DEALLOCATE dbs;
SELECT *
FROM #DataDictionary
ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION;
To get all the columns, just remove the column name comparison in the dynamic code AND c.name = #ColumnName

Find text in my tables, stored procedures, and views in SQL Server

I am able to search for specific text in my views and stored procedure, but I'm not able to search through my tables at the same time.
Here is what I have:
DECLARE #cmd VARCHAR(1000),
#search_string VARCHAR(200)
CREATE TABLE #temp
(
[Database_Name] sysname,
[Schema_Name] sysname,
[Object_Name] sysname,
[Object_Type] nvarchar(60)
)
-- Set the search string
SET #search_string = 'text'
SET #cmd = 'INSERT INTO #temp SELECT DISTINCT ''?'', s.name AS Schema_Name, o.name AS Object_Name, o.type_desc FROM [?].sys.sql_modules m INNER JOIN [?].sys.objects o ON m.object_id = o.object_id INNER JOIN [?].sys.schemas s ON o.schema_id = s.schema_id WHERE m.definition Like ''%' + #search_string + '%'''
-- Uncomment the following if you have problems with your command and want to see the command
--PRINT #cmd
-- Run for every database on the server
EXEC sp_MSforeachdb #cmd
-- Retrieve your results from the temp table
SELECT *
FROM #temp
ORDER BY [Database_Name], [Object_Name], [Object_Type]
-- If you want to omit certain databases from your results, simply add
-- the appropriate WHERE clause, as in the following:
--SELECT *
--FROM #temp
--WHERE db NOT IN ('DB1', 'DB4', 'DB7')
--ORDER BY db, obj_type, obj_name
DROP TABLE #temp
Please try this query for column search
SELECT
t.[name] TableName
, c.[name] ColumnName
FROM sys.columns c
INNER JOIN sys.tables t on t.object_id = c.object_id
WHERE t.[type] = 'U'
AND c.[name] LIKE '%Text%'
Below script will get result for all the databases for both Tables and other obejcts. Hope this will help.
DECLARE #command varchar(1000)
DECLARE #SearchWord VARCHAR(20) = 'Text'
CREATE TABLE #Search (DatabaseName VARCHAR(255),SchemaName VARCHAR(50),ObjectName VARCHAR(255),ObjectType VARCHAR(50))
SET #command = 'USE ? INSERT INTO #Search
SELECT DB_NAME(), SCHEMA_NAME(t.schema_id),t.[name] TableName, ''Table'' FROM sys.columns c INNER JOIN sys.tables t on t.object_id = c.object_id WHERE t.[type] = ''U'' AND c.[name] LIKE ' + '''%' + #SearchWord + '%'''
EXEC sp_MSforeachdb #command;
SET #command = 'USE ? INSERT INTO #Search
SELECT DISTINCT DB_Name(),s.name AS Schema_Name, o.name AS Object_Name, o.type_desc FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id = o.object_id INNER JOIN sys.schemas s ON o.schema_id = s.schema_id WHERE m.definition Like ''%' + #SearchWord + '%'''
EXEC sp_MSforeachdb #command
SELECT * FROM #Search;
DROP TABLE #Search
There is an easy way
select
object= object_name(c.id), o.name , o.type
from sys.syscomments as c
join sys.objects as o on c.id = o.object_id
where c.text like '%Id%'
All compiled objects are in sys.comments, the name changed a few times depending on the version of SQL you have, the sample is from the current version.
Now, one doesn't need to join sys.object as the TSQL is in the text column.
You can look for any string that you have used, table names, field names or code comments. the sample shows %ID% looking for all function, trigger, views procedures that have something that contains the letters ID.
You know that when clicking on an object in SSMS you can select show Dependencies right?

add checking to modify the length of a column ,drop and add the default value in one block

I added a checking on a Varchar column that I want to modify its LENGTH , and its default value
table = EX_EMPLOYEE Column = TV_CODE length =10
My problem : I made 3 blocks to change the length then to drop the default value and add a new one. can I do that in one block ?
is there alternative way for the below its a really long code can I make better checking with less condition and coes ?
BEGIN
DECLARE #OLD_LENGTH numeric(4)
DECLARE #isnull numeric(4)
DECLARE #null_value varchar(10)
SELECT #OLD_LENGTH= c.length,
#isnull = c.isnullable
FROM syscolumns c
WHERE c.id = OBJECT_ID('EX_EMPLOYEE') AND c.name = 'TV_CODE'
if #isnull =1
select #null_value='NULL'
else
select #null_value='NOT NULL'
IF ##ROWCOUNT =0
begin
EXECUTE ('ALTER TABLE EX_EMPLOYEE ALTER COLUMN TV_CODE VARCHAR(11) '+#null_value)
end
if #OLD_LENGTH <11
EXECUTE ('ALTER TABLE EX_EMPLOYEE ALTER COLUMN TV_CODE VARCHAR(11)'+ #null_value)
END
GO
begin
DECLARE #df_value varchar(500)
select #df_value = d.name from sys.all_columns c join sys.tables t on t.object_id = c.object_id join sys.schemas s on s.schema_id = t.schema_id
join sys.default_constraints d on c.default_object_id = d.object_id
where t.name = 'EX_EMPLOYEE' and c.name = 'TV_CODE'
if #df_value is not null
begin
EXECUTE ('ALTER TABLE EX_EMPLOYEE DROP CONSTRAINT '+ #df_value)
end
end
go
IF EXISTS (SELECT 1 FROM sys.all_columns c WHERE c.object_id = OBJECT_ID('EX_EMPLOYEE')
AND c.name = 'TV_CODE')
and NOT EXISTS(select * from sys.all_columns c join sys.tables t on t.object_id = c.object_id join sys.schemas s on s.schema_id = t.schema_id
join sys.default_constraints d on c.default_object_id = d.object_id
where t.name = 'EX_EMPLOYEE' and c.name = 'TV_CODE')
BEGIN
EXECUTE ('ALTER TABLE EX_EMPLOYEE ADD DEFAULT ''A'' for TV_CODE')
END
GO
There’s nothing wrong with the code you have. It can be done as one “block”, and there are ways to make it a bit more efficient, but multiple steps are required for what you are doing, so it will not be short. Here’s how I’d do it, based on the following assumptions:
Everything is in the DBO schema
If the column length is less than 11, do everything, otherwise do nothing
(Me, I’d want to be certain that columns are always NULL or NOT NULL, and don't vary from table instance to table instance. Enforcing this rule with this script would be wise.)
DECLARE
#CurrentLength smallint
,#IsNull bit
,#Command nvarchar(200)
,#Debug bit = 1
-- Get current settings. Note that variables are set to same dataype as is used in the tables
-- Also, always use the system tables in the "sys" schema
SELECT
#CurrentLength = max_length
,#IsNull = is_nullable
from sys.columns
where object_id = object_id('EX_EMPLOYEE')
and name = 'TV_CODE'
IF #CurrentLength < 11
BEGIN
-- Table AND column exist, column is under 11 characters, so proceed with everything
-- Here, reset column to varchar(11)
SET #Command = 'ALTER TABLE EX_EMPLOYEE ALTER COLUMN TV_CODE VARCHAR(11) '
+ case #IsNull
when 1 then 'NULL'
else 'NOT NULL'
end
-- Whenever possible (which I think is always), use sp_executeSQL instead of EXECUTE()
IF #Debug = 1
-- Makes it easier to debug dynamic code
PRINT #Command
EXECUTE sp_executesql #Command
-- Going to cheat here and adapt code from a prior answer https://stackoverflow.com/questions/1430456/how-to-drop-sql-default-constraint-without-knowing-its-name/1433384#1433384
SET #Command = null
SELECT #Command = 'ALTER TABLE EX_EMPLOYEE drop constraint ' + d.name
from sys.tables t
inner join sys.default_constraints d
on d.parent_object_id = t.object_id
inner join sys.columns c
on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where t.name = 'EX_EMPLOYEE'
and c.name = 'TV_CODE'
IF #Debug = 1
-- Continues to make it easier to debug dynamic code
PRINT #Command
-- If there is no constraint, #Command will be null
IF #Command is not null
EXECUTE sp_executesql #Command
-- Now create the default. Give it a name, so we don't have to play "go fish" the next time around.
-- Dynamic SQL is not required here.
ALTER TABLE EX_EMPLOYEE
add constraint DF_EX_EMPLOYEE__TV_CODE
default 'A' for TV_CODE
END
GO

Drop constraint names received from different query

I'm trying to drop a few constraints which have been automatically generated when I add the default value somewhere.
I use the following script to return me the names of the constraints:
SELECT default_constraints.name FROM sys.all_columns
INNER JOIN sys.tables ON all_columns.object_id = tables.object_id
INNER JOIN sys.schemas ON tables.schema_id = schemas.schema_id
INNER JOIN sys.default_constraints ON all_columns.default_object_id = default_constraints.object_id
WHERE tables.name = 'TrainingType'
AND default_constraints.name like 'DF__TrainingT__Soft__%'
OR default_constraints.name like 'DF__TrainingT__EndUs__%'
OR default_constraints.name like 'DF__TrainingC__Compu__%'
This returns me the following:
| name
---------------------------------
1 | DF__TrainingC__Compu__2058C9F1
2 | DF__TrainingT__EndUs__1559B68C
3 | DF__TrainingT__Softw__05CD5A39
Now I'm trying to drop the constraints with these values, but it doesn't allow me to do DROP CONSTRAINT ( ... )
ALTER TABLE TrainingType
DROP CONSTRAINT (
SELECT default_constraints.name FROM sys.all_columns
INNER JOIN sys.tables ON all_columns.object_id = tables.object_id
INNER JOIN sys.schemas ON tables.schema_id = schemas.schema_id
INNER JOIN sys.default_constraints ON all_columns.default_object_id = default_constraints.object_id
WHERE tables.name = 'TrainingType'
AND default_constraints.name like 'DF__TrainingT__Soft__%'
OR default_constraints.name like 'DF__TrainingT__EndUs__%'
OR default_constraints.name like 'DF__TrainingC__Compu__%'
)
So how can I drop the constraints correctly?
Dynamic Sql using the select ... for xml path ('') method of string concatenation to concatenate the commands into one variable to execute with sp_executesql:
declare #sql nvarchar(max);
select #sql = (
select
'alter table '+quotename(schema_name(dc.schema_id))
+'.'+quotename(object_name(dc.parent_object_id))
+' drop constraint '+quotename(name)+';'+char(10)
from sys.default_constraints as dc
where parent_object_id = object_id(N'TrainingType')
and dc.name like 'DF__TrainingT__Soft__%'
or dc.name like 'DF__TrainingT__EndUs__%'
or dc.name like 'DF__TrainingC__Compu__%'
for xml path (''), type).value('.','nvarchar(max)')
set #sql = 'use '+quotename(db_name())+';'+char(10)+#sql;
select #sql
exec sp_executesql #sql;
This is a good primer on dynamic sql:
The curse and blessings of dynamic SQL - Erland Sommarskog
rextester demo: http://rextester.com/HSV25230
Generated code from the demo:
use [rextester];
alter table [dbo].[Pilots] drop constraint [DF__Pilots__df__173EF6DF];
alter table [dbo].[Pilots] drop constraint [DF__Pilots__other_df__18331B18];
Maybe it'll work once you add the ID as column and name as a second column.
This should be the proper syntax:
ALTER TABLE "table_name"
DROP [CONSTRAINT|INDEX] "CONSTRAINT_NAME";
You can't inject dynamic qualifiers into a drop clause like that. They have to be issued one at a time. A similar method would be to generate a script to run as individual sql commands.
SELECT
'ALTER TABLE TrainingType DROP CONSTRAINT ( '
+ default_constraints.name +')'
+ CHAR(10)+CHAR(13)+ GO '
FROM sys.all_columns
INNER JOIN sys.tables ON all_columns.object_id = tables.object_id
....
You now have one statement per drop command that you can apply against your database.

Search text in stored procedure in SQL Server

I want to search a text from all my database stored procedures. I use the below SQL:
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc
FROM sys.sql_modules m
INNER JOIN
sys.objects o
ON m.object_id = o.object_id
WHERE m.definition Like '%[ABD]%';
I want to search for [ABD] in all stored procedures including square brackets, but it's not giving the proper result. How can I change my query to achieve this?
Escape the square brackets:
...
WHERE m.definition Like '%\[ABD\]%' ESCAPE '\'
Then the square brackets will be treated as a string literals not as wild cards.
Try this request:
Query
SELECT name
FROM sys.procedures
WHERE Object_definition(object_id) LIKE '%strHell%'
Have you tried using some of the third party tools to do the search? There are several available out there that are free and that saved me a ton of time in the past.
Below are two SSMS Addins I used with good success.
ApexSQL Search – Searches both schema and data in databases and has additional features such as dependency tracking and more…
SSMS Tools pack – Has same search functionality as previous one and several other cool features. Not free for SQL Server 2012 but still very affordable.
I know this answer is not 100% related to the questions (which was more specific) but hopefully others will find this useful.
I usually run the following to achieve that:
select distinct object_name(id)
from syscomments
where text like '%[ABD]%'
order by object_name(id)
Good practice to work with SQL Server.
Create below stored procedure and set short key,
CREATE PROCEDURE [dbo].[Searchinall]
(#strFind AS VARCHAR(MAX))
AS
BEGIN
SET NOCOUNT ON;
--TO FIND STRING IN ALL PROCEDURES
BEGIN
SELECT OBJECT_NAME(OBJECT_ID) SP_Name
,OBJECT_DEFINITION(OBJECT_ID) SP_Definition
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL VIEWS
BEGIN
SELECT OBJECT_NAME(OBJECT_ID) View_Name
,OBJECT_DEFINITION(OBJECT_ID) View_Definition
FROM sys.views
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL FUNCTION
BEGIN
SELECT ROUTINE_NAME Function_Name
,ROUTINE_DEFINITION Function_definition
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%'+#strFind+'%'
AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY
ROUTINE_NAME
END
--TO FIND STRING IN ALL TABLES OF DATABASE.
BEGIN
SELECT t.name AS Table_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 '%'+#strFind+'%'
ORDER BY
Table_Name
END
END
Now - Set short key as below,
So next time whenever you want to find a particular text in any of the four objects like Store procedure, Views, Functions and Tables. You just need to write that keyword and press shortcut key.
For example: I want to search 'PaymentTable' then write 'PaymentTable' and make sure you select or highlight the written keyword in query editor and press shortcut key ctrl+4 - it will provide you full result.
Redgate's SQL Search is a great tool for doing this, it's a free plugin for SSMS.
Please take this as a "dirty" alternative but this saved my behind many times especially when I was not familiar with the DB project. Sometimes you are trying to search for a string within all SPs and forget that some of the related logic may have been hiding between Functions and Triggers or it can be simply worded differently than you thought.
From your MSSMS you may right click your DB and select
Tasks -> Generate Scripts wizard to output all the SPs, Fns and Triggers into a single .sql file.
Make sure to select Triggers too!
Then just use Sublime or Notepad to search for the string you need to find. I know this may be quite inefficient and paranoid approach but it works :)
You can also use this one:
SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION like '%Search_String%'
select top 10 * from
sys.procedures
where object_definition(object_id) like '%\[ABD\]%'
It might help you!
SELECT DISTINCT
A.NAME AS OBJECT_NAME,
A.TYPE_DESC
FROM SYS.SQL_MODULES M
INNER JOIN SYS.OBJECTS A ON M.OBJECT_ID = A.OBJECT_ID
WHERE M.DEFINITION LIKE '%['+#SEARCH_TEXT+']%'
ORDER BY TYPE_DESC
Also you can use:
SELECT OBJECT_NAME(id)
FROM syscomments
WHERE [text] LIKE '%flags.%'
AND OBJECTPROPERTY(id, 'IsProcedure') = 1
GROUP BY OBJECT_NAME(id)
Thats include comments
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc
FROM sys.sql_modules m INNER JOIN sys.objects o
ON m.object_id = o.object_id WHERE m.definition Like '%[String]%';
SELECT DISTINCT OBJECT_NAME([id]),[text]
FROM syscomments
WHERE [id] IN (SELECT [id] FROM sysobjects WHERE xtype IN
('TF','FN','V','P') AND status >= 0) AND
([text] LIKE '%text to be search%' )
OBJECT_NAME([id]) --> Object Name (View,Store Procedure,Scalar Function,Table function name)
id (int) = Object identification number
xtype char(2) Object type. Can be one of the following object types:
FN = Scalar function
P = Stored procedure
V = View
TF = Table function
SELECT name , type_desc , create_date , modify_date
FROM sys.procedures
WHERE Object_definition(object_id) LIKE '%High%'
I created a procedure to search text in procedures/functions, tables, views, or jobs. The first parameter #search is the search criterion, #target the search target, i.e., procedures, tables, etc. If not specified, search all. #db is to specify the database to search, default to your current database. Here is my query in dynamic SQL.
ALTER PROCEDURE [dbo].[usp_find_objects]
(
#search VARCHAR(255),
#target VARCHAR(255) = NULL,
#db VARCHAR(35) = NULL
)
AS
SET NOCOUNT ON;
DECLARE #TSQL NVARCHAR(MAX), #USEDB NVARCHAR(50)
IF #db <> '' SET #USEDB = 'USE ' + #db
ELSE SET #USEDB = ''
IF #target IS NULL SET #target = ''
SET #TSQL = #USEDB + '
DECLARE #search VARCHAR(128)
DECLARE #target VARCHAR(128)
SET #search = ''%' + #search + '%''
SET #target = ''' + #target + '''
IF #target LIKE ''%Procedure%'' BEGIN
SELECT o.name As ''Stored Procedures''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype IN (''P'',''FN'')
GROUP BY o.name
ORDER BY o.name
END
ELSE IF #target LIKE ''%View%'' BEGIN
SELECT o.name As ''Views''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype = ''V''
GROUP BY o.name
ORDER BY o.name
END
/* Table - search table name only, need to add column name */
ELSE IF #target LIKE ''%Table%'' BEGIN
SELECT t.name AS ''TableName''
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE #search
ORDER BY TableName
END
ELSE IF #target LIKE ''%Job%'' BEGIN
SELECT j.job_id,
s.srvname,
j.name,
js.step_id,
js.command,
j.enabled
FROM [msdb].dbo.sysjobs j
JOIN [msdb].dbo.sysjobsteps js
ON js.job_id = j.job_id
JOIN master.dbo.sysservers s
ON s.srvid = j.originating_server_id
WHERE js.command LIKE #search
END
ELSE BEGIN
SELECT o.name As ''Stored Procedures''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype IN (''P'',''FN'')
GROUP BY o.name
ORDER BY o.name
SELECT o.name As ''Views''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype = ''V''
GROUP BY o.name
ORDER BY o.name
SELECT t.name AS ''Tables''
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE #search
ORDER BY Tables
SELECT j.name AS ''Jobs''
FROM [msdb].dbo.sysjobs j
JOIN [msdb].dbo.sysjobsteps js
ON js.job_id = j.job_id
JOIN master.dbo.sysservers s
ON s.srvid = j.originating_server_id
WHERE js.command LIKE #search
END
'
EXECUTE sp_executesql #TSQL
Update:
If you renamed a procedure, it only updates sysobjects but not syscomments, which keeps the old name and therefore that procedure will not be included in the search result unless you drop and recreate the procedure.
also try this :
SELECT ROUTINE_NAME
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION like '%\[ABD\]%'
A different version, To make query more appropriate for different coding practices.
SELECT DISTINCT
O.NAME AS OBJECT_NAME,
O.TYPE_DESC
FROM SYS.SQL_MODULES M
INNER JOIN
SYS.OBJECTS O
ON M.OBJECT_ID = O.OBJECT_ID
WHERE UPPER(M.DEFINITION) LIKE UPPER('%Your Text%');
Using CHARINDEX:
SELECT DISTINCT o.name AS Object_Name,o.type_desc
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON m.object_id=o.object_id
WHERE CHARINDEX('[ABD]',m.definition) >0 ;
Using PATINDEX:
SELECT DISTINCT o.name AS Object_Name,o.type_desc
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON m.object_id=o.object_id
WHERE PATINDEX('[[]ABD]',m.definition) >0 ;
Using this double [[]ABD] is similar to escaping :
WHERE m.definition LIKE '%[[]ABD]%'
This query is search text in stored procedure from all databases.
DECLARE #T_Find_Text VARCHAR(1000) = 'Foo'
IF OBJECT_ID('tempdb..#T_DBNAME') IS NOT NULL DROP TABLE #T_DBNAME
IF OBJECT_ID('tempdb..#T_PROCEDURE') IS NOT NULL DROP TABLE #T_PROCEDURE
CREATE TABLE #T_DBNAME
(
IDX int IDENTITY(1,1) PRIMARY KEY
, DBName VARCHAR(255)
)
CREATE TABLE #T_PROCEDURE
(
IDX int IDENTITY(1,1) PRIMARY KEY
, DBName VARCHAR(255)
, Procedure_Name VARCHAR(MAX)
, Procedure_Description VARCHAR(MAX)
)
INSERT INTO #T_DBNAME (DBName)
SELECT name FROM master.dbo.sysdatabases
DECLARE #T_C_IDX INT = 0
DECLARE #T_C_DBName VARCHAR(255)
DECLARE #T_SQL NVARCHAR(MAX)
DECLARE #T_SQL_PARAM NVARCHAR(MAX)
SET #T_SQL_PARAM =
' #T_C_DBName VARCHAR(255)
, #T_Find_Text VARCHAR(255)
'
WHILE EXISTS(SELECT TOP 1 IDX FROM #T_DBNAME WHERE IDX > #T_C_IDX ORDER BY IDX ASC)
BEGIN
SELECT TOP 1
#T_C_DBName = DBName
FROM #T_DBNAME WHERE IDX > #T_C_IDX ORDER BY IDX ASC
SET #T_SQL = ''
SET #T_SQL = #T_SQL + 'INSERT INTO #T_PROCEDURE(DBName, Procedure_Name, Procedure_Description)'
SET #T_SQL = #T_SQL + 'SELECT SPECIFIC_CATALOG, ROUTINE_NAME, ROUTINE_DEFINITION '
SET #T_SQL = #T_SQL + 'FROM ' + #T_C_DBName + '.INFORMATION_SCHEMA.ROUTINES '
SET #T_SQL = #T_SQL + 'WHERE ROUTINE_DEFINITION LIKE ''%''+ #T_Find_Text + ''%'' '
SET #T_SQL = #T_SQL + 'AND ROUTINE_TYPE = ''PROCEDURE'' '
BEGIN TRY
EXEC SP_EXECUTESQL #T_SQL, #T_SQL_PARAM, #T_C_DBName, #T_Find_Text
END TRY
BEGIN CATCH
SELECT #T_C_DBName + ' ERROR'
END CATCH
SET #T_C_IDX = #T_C_IDX + 1
END
SELECT IDX, DBName, Procedure_Name FROM #T_PROCEDURE ORDER BY DBName ASC
Select distinct OBJECT_NAME(id) from syscomments where text like '%string%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1
/*
SEARCH SPROCS & VIEWS
The following query will allow search within the definitions
of stored procedures and views.
It spits out the results as XML, with the full definitions,
so you can browse them without having to script them individually.
*/
/*
STEP 1: POPULATE SEARCH KEYS. (Set to NULL to ignore)
*/
DECLARE
#def_key varchar(128) = '%foo%', /* <<< definition search key */
#name_key varchar(128) = '%bar%', /* <<< name search key */
#schema_key varchar(128) = 'dbo'; /* <<< schema search key */
;WITH SearchResults AS (
/*
STEP 2: DEFINE SEARCH QUERY AS CTE (Common Table Expression)
*/
SELECT
[Object].object_id AS [object_id],
[Schema].name AS [schema_name],
[Object].name AS [object_name],
[Object].type AS [object_type],
[Object].type_desc AS [object_type_desc],
[Details].definition AS [module_definition]
FROM
/* sys.sql_modules = where the body of sprocs and views live */
sys.sql_modules AS [Details] WITH (NOLOCK)
JOIN
/* sys.objects = where the metadata for every object in the database lives */
sys.objects AS [Object] WITH (NOLOCK) ON [Details].object_id = [Object].object_id
JOIN
/* sys.schemas = where the schemas in the datatabase live */
sys.schemas AS [Schema] WITH (NOLOCK) ON [Object].schema_id = [Schema].schema_id
WHERE
(#def_key IS NULL OR [Details].definition LIKE #def_key) /* <<< searches definition */
AND (#name_key IS NULL OR [Object].name LIKE #name_key) /* <<< searches name */
AND (#schema_key IS NULL OR [Schema].name LIKE #schema_key) /* <<< searches schema */
)
/*
STEP 3: SELECT FROM CTE INTO XML
*/
/*
This outer select wraps the inner queries in to the <sql_object> root element
*/
SELECT
(
/*
This inner query maps stored procedure rows to <procedure> elements
*/
SELECT TOP 100 PERCENT
[object_id] AS [#object_id],
[schema_name] + '.' + [object_name] AS [#full_name],
[module_definition] AS [module_definition]
FROM
SearchResults
WHERE
object_type = 'P'
ORDER BY
[schema_name], [object_name]
FOR XML
PATH ('procedure'), TYPE
) AS [procedures], /* <<< as part of the outer query,
this alias causes the <procedure> elements
to be wrapped within the <procedures> element */
(
/*
This inner query maps view rows to <view> elements
*/
SELECT TOP 100 PERCENT
[object_id] AS [#object_id],
[schema_name] + '.' + [object_name] AS [#full_name],
[module_definition] AS [module_definition]
FROM
SearchResults
WHERE
object_type = 'V'
ORDER BY
[schema_name], [object_name]
FOR XML
PATH ('view'), TYPE
) AS [views] /* <<< as part of the outer query,
this alias causes the <view> elements
to be wrapped within the <views> element */
FOR XML
PATH ('sql_objects')
Every so often I use this script to figure out which procs to modify, or to figure out what uses a column of a table, or that table at all to remove some old junk. It checks each database on the instance it is ran on by the wonderfully supplied sp_msforeachdb.
if object_id('tempdb..##nothing') is not null
drop table ##nothing
CREATE TABLE ##nothing
(
DatabaseName varchar(30),
SchemaName varchar(30),
ObjectName varchar(100),
ObjectType varchar(50)
)
EXEC master.sys.sp_msforeachdb
'USE ?
insert into ##nothing
SELECT
db_name() AS [Database],
[Scehma]=schema_name(o.schema_id),
o.Name,
o.type
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON o.object_id = m.object_id
WHERE
m.definition like ''%SOME_TEXT%'''
--edit this text
SELECT * FROM ##nothing n
order by OBJECTname
-- Applicable for SQL 2005+
USE YOUR_DATABASE_NAME //;
GO
SELECT [Scehma] = schema_name(o.schema_id)
,o.NAME
,o.type
FROM sys.sql_modules m
INNER JOIN sys.objects o ON o.object_id = m.object_id
WHERE m.DEFINITION LIKE '%YOUR SEARCH KEYWORDS%'
GO
This search routine is based on https://stackoverflow.com/a/33631029/2735286 and contains the schema name too in the search results:
CREATE PROCEDURE [dbo].[Searchinall] (#strFind AS VARCHAR(MAX))
AS
BEGIN
SET NOCOUNT ON;
--TO FIND STRING IN ALL PROCEDURES
BEGIN
SELECT s.name SP_Schema_Name, OBJECT_NAME(p.OBJECT_ID) SP_Name
,OBJECT_DEFINITION(p.OBJECT_ID) SP_Definition
FROM sys.procedures p
INNER JOIN sys.schemas s on p.schema_id = s.schema_id
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL VIEWS
BEGIN
SELECT s.name SP_Schema_Name, OBJECT_NAME(OBJECT_ID) View_Name
,OBJECT_DEFINITION(OBJECT_ID) View_Definition
FROM sys.views v
INNER JOIN sys.schemas s on v.schema_id = s.schema_id
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL FUNCTION
BEGIN
SELECT ROUTINE_SCHEMA, ROUTINE_NAME Function_Name
,ROUTINE_DEFINITION Function_definition
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%'+#strFind+'%'
AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY
ROUTINE_NAME
END
--TO FIND STRING IN ALL TABLES OF DATABASE.
BEGIN
SELECT s.name SP_Schema_Name, t.name AS Table_Name
,c.name AS COLUMN_NAME
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.schemas s on t.schema_id = s.schema_id
WHERE c.name LIKE '%'+#strFind+'%'
ORDER BY
Table_Name
END
END
Here is how you use it:
execute [dbo].[Searchinall] 'cust'
Here is an alternative which lists all objects with a specific keyword in one single query:
SELECT DISTINCT
s.name AS Schema_Name,
o.name AS Object_Name,
o.type_desc
FROM sys.sql_modules m
INNER JOIN
sys.objects o
ON m.object_id = o.object_id
INNER JOIN sys.schemas s on o.schema_id = s.schema_id
WHERE m.definition Like '%dim_forex%' ESCAPE '\' order by 3;
This query should return the same results and the procedure call in this answer.
You can also use
CREATE PROCEDURE [Search](
#Filter nvarchar(max)
)
AS
BEGIN
SELECT name
FROM procedures
WHERE definition LIKE '%'+#Filter+'%'
END
and then run
exec [Search] 'text'