Search for column in entire SQL database - sql-server

I need to change a column's data type but I do not every location in the database that might be referencing it. Is there a script or application that can search all views, stored procedures, functions, table computed columns, etc. within a database and show what is referencing the column? I am using SQL Server 2005 Standard.
Thanks,
Aaron

You can always inspect the sys.columns catalog view:
SELECT
c.NAME 'Col Name',
OBJECT_NAME(c.OBJECT_ID) 'Table Name',
t.name
FROM
sys.columns c
INNER JOIN
sys.types t ON c.system_type_id = t.system_type_id
WHERE
c.Name = 'your-column-name-here'
and based on that information, you can generate the ALTER statements for a database:
SELECT
'ALTER TABLE dbo.' + OBJECT_NAME(c.OBJECT_ID) +
' ALTER COLUMN ' + c.NAME ' NewDataType NULL'
FROM
sys.columns c
WHERE
c.Name = 'your-column-name-here'
This query generates a set of ALTER TABLE .... statements which you can then copy to a SSMS query window and execute.
Word of warning: if any of the columns are being referenced - in a foreign key relationship, or if there's a default or check constraint on them - this approach might fail. In that case, you'd need to do some extra steps for those columns (like drop the constraints first etc.)
Update: this searches for the columns as defined in tables.
If you need to search into stored procedures, view and functions as well, I would strongly recommend using Red-Gate's excellent and free (!!) SQL Search utility - excellent stuff!

I like using a free search add-in tool from redgate software. I'm amazed at how useful it is - you can find all references to text quickly with it.
This description is from SQL Curry:
SQL Search finds fragments of SQL text within stored procedures, functions, views and more and once you find them, it quickly allows you to click and jump to the objects, wherever they happen to be on your servers. It’s pretty cool!
Here is the link: SQL Search

This query will help you find any table's column and the column it is referring to -
SELECT OBJECT_NAME(f.parent_object_id) AS [Table], COL_NAME(fc.parent_object_id,fc.parent_column_id) AS [Column],
OBJECT_NAME (f.referenced_object_id) AS RefTable, COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS RefColumn,
f.name AS FK
FROM sys.foreign_keys AS f INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
WHERE OBJECT_NAME(f.parent_object_id) = '<your table name>'
AND COL_NAME(fc.parent_object_id,fc.parent_column_id) = '<your column name>'

I work for Red Gate and I see that SQL Search as already been mentioned. Glad that works for you. Another tool that can specifically list column dependencies is SQL Prompt 5, due to be released soon. You can download the EA build by visiting: http://www.surveymk.com/s.aspx?sm=zDJogAY5rwdIwOX/SqtTCQ%3d%3d and joining the early access list. I'd welcome you to try this out and let me know if it doesn't match your requirements. Another great feature it has is the ability to list your invalid objects. In other words, if you rename a column and you have a stored procedure that references the old column, it will draw your attention to this.

Related

SQL Server Management Studio quickly locate column?

I'm using SSMS and our tables have a lot of columns, so it gets frustrating trying to scroll and try to find a column. Is there a way to quickly locate a column?
You can select from the sys tables
select c.name
from sys.columns c
inner join sys.tables t on t.object_id = c.object_id
where t.name = 'YOURTABLENAME'
and c.name like '%column looking for%'
If you need to find database objects (e.g. tables, columns, triggers) by name - have a look at the FREE Red-Gate tool called SQL Search which does this - it searches your entire database for any kind of string(s).
It's a great must-have tool for any DBA or database developer - did I already mention it's absolutely FREE to use for any kind of use??

How to get properties of a field of table in sybase

Here is details
In sybase, I have a table "abc" having 5 fields(name, roll, address, desc,path). If i would use 'sp_help tablename' then i can see all properties of all fields how i can get properties of a particular field i.e. roll or any one field and their properties using sql or pl/sql.
As we know that we can not use any parameters in sp_help so is there any way to to get the properties of a field, (pl/sql or sql)?
Thanks in advance
sp_help tablename
This depends on what specific properties you are looking for. Assuming you are looking for Table, Column, Datatype, Datatype Length - you have to join sysobjects, syscolumns, and systypes
use YOURDB
go
select o.name, c.name, t.usertype, c.length
from
sysobject o,
syscolumns c,
systypes t
where o.id = c.id
and c.usertype = t.usertype
and o.name like "YOUR_TABLE"
and c.name like "YOUR_COLUMN"
go
If you want more than that, you'll have to bring in other columns and/or tables into the query like sysdepends, sysdefaults or sysconstraints
More information about the system tables can be found here:
Sybase ASE Reference Manual: Tables > System Tables
And the system table diagram, which shows the column mappings can be found here:
http://infocenter.sybase.com/help/topic/com.sybase.infocenter.dc70204.1550/pdf/a155pst.pdf
Also, FYI - Sybase uses T-SQL (like SQL Server), not pl/sql.

How do I create and use a stored procedure for SQL-Sever which will delete the data in all tables in a database with VS 2010?

I've been using the entities framework with ASP.NET MVC and I'm looking for an easy and fast way to drop all of the information in the database. It takes quite a while to delete all of the information from the entities object and then save the changes to the database (probably because there are a lot of many-to-many relationships) and I think it should be really fast to just remove all of the information with a stored procedure but I'm not sure how to go about this. How do I create and use a stored procedure for SQL-Sever which will delete the data in all tables in a database with VS 2010? Also if I do this will the command be compatible with other version of SQL-Server? (I'm using 2008 on my testing comptuer, but when I upload it I not sure if my hosting company uses 2008 or 2005).
Thanks!!
This solution will work well in terms of deleting all your data in your database's tables.
You can create this stored proc right within Visual Studio on your SQL Server 2008 development server. It'll work well in any version of SQL Server (2000+).
CREATE PROC NukeMyDatabase
AS
--order is important here. delete data in FK'd tables first.
DELETE Foo
DELETE Bar
TRUNCATE TABLE Baz
I prefer TRUNCATE TABLE, as it's faster. It'll depend on your data model, as you can't issue a TRUNCATE TABLE on a table referenced by a foreign key constraint (i.e. parent tables).
You could then call this stored proc using Entity Framework after adding it to your .edmx:
myContext.NukeMyDatabase();
I recently faced a similar problem in that I had to clear over 200+ tables that were interlinked through many foreign key constraints.
The critical issue, as p.campbell pointed out, is determining the correct order of DELETE statements.
The foreign key constraints between tables essentially represent a hierarchy. If table 3 is dependent on table 2, and table 2 is dependent on table 1, then table 1 is the root and table 3 is the leaf.
In other words, if your going to delete from these three tables, you have to start with the table that has no dependencies and work your way up. That is the intent of this code:
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
;WITH c AS
(
SELECT
parent_object_id AS org_child,
parent_object_id,
referenced_object_id,
1 AS Depth
FROM sys.foreign_keys
UNION ALL
SELECT
c.org_child,
k.parent_object_id,
k.referenced_object_id,
Depth + 1
FROM c
INNER JOIN sys.foreign_keys k
ON c.referenced_object_id = k.parent_object_id
WHERE c.parent_object_id != k.referenced_object_id
),
c2 AS (
SELECT
OBJECT_NAME(org_child) AS ObjectName,
MAX(Depth) AS Depth
FROM c
GROUP BY org_child
UNION ALL
SELECT
OBJECT_NAME(object_id),
0 AS Depth
FROM sys.objects o
LEFT OUTER JOIN c
ON o.object_id = c.org_child
WHERE c.org_child IS NULL
AND o.type = 'U'
)
SELECT #sql = #sql + 'DELETE FROM ' + CAST(ObjectName AS VARCHAR(100))
+ ';' + CHAR(13) + CHAR(10) /** for readability in PRINT statement */
FROM c2
ORDER BY Depth DESC
PRINT #sql
/** EXEC (#sql) **/
exec sp_MSForEachTable 'truncate table ?';
But I would recommend a different approach: take a backup of the empty database and simply restore this backup before each run. Even better, have no database at all and have your application be capable of deploying the database itself, using a schema version upgrade set of scripts.

How can I tell if a database table is being accessed anymore? Want something like a "SELECT trigger"

I have a very large database with hundreds of tables, and after many, many product upgrades, I'm sure half of them aren't being used anymore. How can I tell if a table is is actively being selected from? I can't just use Profiler - not only do I want to watch for more than a few days, but there are thousands of stored procedures as well, and profiler won't translate the SP calls into table access calls.
The only thing I can think of is to create a clustered index on the tables of interest, and then monitor the sys.dm_db_index_usage_stats to see if there are any seeks or scans on the clustered index, meaning that data from the table was loaded. However, adding a clustered index on every table is a bad idea (for any number of reasons), as isn't really feasible.
Are there other options I have? I've always wanted a feature like a "SELECT trigger", but there are probably other reasons why SQL Server doesn't have that feature either.
SOLUTION:
Thanks, Remus, for pointing me in the right direction. Using those columns, I've created the following SELECT, which does exactly what I want.
WITH LastActivity (ObjectID, LastAction) AS
(
SELECT object_id AS TableName,
last_user_seek as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
UNION
SELECT object_id AS TableName,
last_user_scan as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
UNION
SELECT object_id AS TableName,
last_user_lookup as LastAction
FROM sys.dm_db_index_usage_stats u
WHERE database_id = db_id(db_name())
)
SELECT OBJECT_NAME(so.object_id) AS TableName,
MAX(la.LastAction) as LastSelect
FROM sys.objects so
LEFT
JOIN LastActivity la
on so.object_id = la.ObjectID
WHERE so.type = 'U'
AND so.object_id > 100
GROUP BY OBJECT_NAME(so.object_id)
ORDER BY OBJECT_NAME(so.object_id)
Look in sys.dm_db_index_usage_stats. The columns last_user_xxx will contain the last time the table was accessed from user requests. This table resets its tracking after a server restart, so you must leave it running for a while before relying on its data.
Re: Profiler, if you monitor for SP:StmtCompleted, that will capture all statements executing within a stored procedure, so that will catch table accesses within a sproc. If not everything goes through stored procedures, you may also need the SQL:StmtCompleted event.
There will be a large number of events so it's probably still not practical to trace over a long time due to the size of trace. However, you could apply a filter - e.g. where TextData contains the name of your table you want to check for. You could give a list of table names to filter on at any one time and work through them gradually. So you should not get any trace events if none of those tables have been accessed.
Even if you feel it's not a suitable/viable approach for you, I thought it was worth expanding on.
Another solution would be to do a global search of your source code to find references to the tables. You can query the stored procedure definitions to check for matches for a given table, or just generate a complete database script and do a Find on that for table names.
For SQL Server 2008 you should take a look at SQL Auditing. This allows you to audit many things including selects on a table and reports to a file or Events Log.
The following query uses the query plan cache to see if there's a reference to a table in any of the existing plans in cache. This is not guaranteed to be 100% accurate (since query plans are flushed out if there are memory constraints) but can be used to get some insights on table use.
SELECT schema_name(schema_id) as schemaName, t.name as tableName,
databases.name,
dm_exec_sql_text.text AS TSQL_Text,
dm_exec_query_stats.creation_time,
dm_exec_query_stats.execution_count,
dm_exec_query_stats.total_worker_time AS total_cpu_time,
dm_exec_query_stats.total_elapsed_time,
dm_exec_query_stats.total_logical_reads,
dm_exec_query_stats.total_physical_reads,
dm_exec_query_plan.query_plan
FROM sys.dm_exec_query_stats
CROSS APPLY sys.dm_exec_sql_text(dm_exec_query_stats.plan_handle)
CROSS APPLY sys.dm_exec_query_plan(dm_exec_query_stats.plan_handle)
INNER JOIN sys.databases ON dm_exec_sql_text.dbid = databases.database_id
RIGHT JOIN sys.tables t (NOLOCK) ON cast(dm_exec_query_plan.query_plan as varchar(max)) like '%' + t.name + '%'
I had in mind to play with user permissions for different tables, but then I remembered you can turn on trace with an ON LOGON trigger you might benefit from this:
CREATE OR REPLACE TRIGGER SYS.ON_LOGON_ALL
AFTER LOGON ON DATABASE
WHEN (
USER 'MAX'
)
BEGIN
EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE';
--EXECUTE IMMEDIATE 'alter session set events ''10046 trace name context forever level 12''';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
/
Then you can check your trace files.
This solution works better for me then the solution above. But, is still limted that the server was not re-started as well, but still gives you a good idea of tables not used.
SELECT [name]
,[object_id]
,[principal_id]
,[schema_id]
,[parent_object_id]
,[type]
,[type_desc]
,[create_date]
,[modify_date]
,[is_ms_shipped]
,[is_published]
,[is_schema_published]
FROM [COMTrans].[sys].[all_objects]
where object_id not in (
select object_id from sys.dm_db_index_usage_stats
)
and type='U'
order by name

In SQL Server, how do I identify *all* dependencies for a specific table using system tables/views?

I am writing a DDL script to drop a number of tables but need to identify all dependencies for those tables first. Those dependencies include foreign key constraints, stored procedures, views, etc. Preferably, I want to programmatically script out dropping those dependencies using the system tables/views before dropping the dependent table.
This is extremely messy to write from scratch. Have you considered a 3rd party tool like
Red-Gate SQL Dependency Tracker?
sp_depends is not reliable see: Do you depend on sp_depends (no pun intended)
you could always search through the syscomments table....that might take a while though...
Could you reference sysreferences?
select 'if exists (select name from sysobjects where name = '''+c.name+''') '
+' alter table ' + t.name +' drop constraint '+ c.name
from sysreferences sbr, sysobjects c, sysobjects t, sysobjects r
where c.id = constrid
and t.id = tableid
and reftabid = r.id
and r.name = 'my_table'
That will generate a whole lot of conditional drop constraint calls. Should work.
You can use the sp_depends stored procedure to do this:
USE AdventureWorks
GO
EXEC sp_depends #objname = N'Sales.Customer' ;
http://msdn.microsoft.com/en-us/library/ms189487(SQL.90).aspx

Resources