Identify column-level dependencies between databases - sql

Is there a way to identify column-level dependencies within and between databases? I'd like to generate a report of all columns in a database that are unused by anything (views, procs, UDFs).
e.g.
In database 'DB1', there is a table with a column called 'col1'. How do I determine if 'col1' is being used by procs, views or UDFs in either database 'DB1' or a second database 'DB2'?
Thank you

You can try using:
SELECT OBJECT_NAME(m.object_id), m.*
FROM SYS.SQL_MODULES m
WHERE m.definition LIKE N'%my_column_name%'
SYSCOMMENTS and INFORMATION_SCHEMA.routines have nvarchar(4000) columns. So if "my_column_name" is used at position 3998, it won't be found. SYSCOMMENTS does have multiple lines, but ROUTINES truncates.
But that won't be any help for SELECT * situations, because the column name won't be in text.

If it's only col1, db1, and db2, you can script out the objects in db1 and db2 and search for references to col1.

Related

SQL Server - rename and merge databases with legacy support

I have two Sql Server 2008 R2 databases, called MyDbOne and MyDbTwo.
I'd like to merge them (all tables and procedures) into a new database called MyDb.
Assume there are no conflicts in table and procedure names between them.
The problem is: there are LOTS of code and procedures that execute queries using the database name, including procedures declared in one of the databases referecing tables from the other. There are queries like:
select * from MyDbOne..SomeTable;
select * from MyDbTwo..AnotherTable;
The tables SomeTable and AnotherTable would then exist in the MyDb database. But I need to support querying them using the leagcy names MyDbOne and MyDbTwo. If I would run the queries above, I'd like them to be effectively the same as:
select * from MyDb..SomeTable;
select * from MyDb..AnotherTable;
Is there some way to do it? Maybe create some sort of global aliases on the new database, resolving MyDbOne and MyDbTwo to MyDb? That would be perfect, but I don't know how to do it.
Thank you ver much!
There's no easy way around it. You'll have to update all those references manually. You can search the SQL server for all objects containing those database names by using one of these queries from this answer;
SELECT ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%Foo%'
AND ROUTINE_TYPE='PROCEDURE'
SELECT OBJECT_NAME(id)
FROM SYSCOMMENTS
WHERE [text] LIKE '%Foo%'
AND OBJECTPROPERTY(id, 'IsProcedure') = 1
GROUP BY OBJECT_NAME(id)
SELECT OBJECT_NAME(object_id)
FROM sys.sql_modules
WHERE OBJECTPROPERTY(object_id, 'IsProcedure') = 1
AND definition LIKE '%Foo%'
I don't think there is an issue solution to this. If I were you, I would keep existing MyDbOne and MyDbTwo databases intact and create a brand new one that references these two tables via views. Basically, you will create a Data Warehouse that seats on top of these existing databases. Good thing about this setup is, you don't have to rewrite any legacy code, which is huge.

How do I get a list of columns in a table or view?

On occasion, I'm interested in getting a list of columns in one of the tables or views in my SQL Server 2008 R2 database. It's useful, for example, if you're building database documentation without using an expensive off-the-shelf product.
What's an easy way to get this information?
In SQL Server 2008 R2 (among other versions), there are system views provided automatically with every database. As long as you are connected to the database where your table resides, you can run a query like this:
DECLARE #TableViewName NVARCHAR(128)
SET #TableViewName=N'MyTableName'
SELECT b.name AS ColumnName, c.name AS DataType,
b.max_length AS Length, c.Precision, c.Scale, d.value AS Description
FROM sys.all_objects a
INNER JOIN sys.all_columns b
ON a.object_id=b.object_id
INNER JOIN sys.types c
ON b.user_type_id=c.user_type_id
LEFT JOIN sys.extended_properties d
ON a.object_id=d.major_id AND b.column_id=d.minor_id AND d.name='MS_Description'
WHERE a.Name=#TableViewName
AND a.type IN ('U','V')
Of course, this is just a starting point. There are many other system views and columns available in every database. You can find them through SQL Server Management Studio under Views > "System Views
Another way is querying the INFORMATION_SCHEMA.columns view as detailed here:
Information_Schema - COLUMNS
This will give you information for all the columns in the current database (and what table/view they belong to) including their datatypes, precision, collation and whether they allow nulls etc
Usefully as well, these views are maintained in multiple DBMS programs too, so you could potentially use the same or similar query to get the same information regarding a MySQL database as you can a SQL Server DB, which could be useful if you are developing on multiple platorms.
sp_columns returns detailed information about each of the columns in the table. SO Answer
sp_columns #tablename
sp_help returns detailed information about the entire table including the columns and constraints. SO Answer
sp_help #tablename
To get a list of Columns of a view with some other information about the column you can use the following:
SELECT * FROM sys.columns c, sys.views v
WHERE c.object_id = v.object_id
AND v.name = 'view_Name'
GO
And if you only want the list of Column Name use this.
SELECT c.name
FROM sys.columns c, sys.views v
WHERE c.object_id = v.object_id
AND v.name = 'view_UserAssessphers'
GO
exec sp_helptext <your view name>
Also works for the view only, blachniet's answer is best if you need details on the columns in the table.
In a new query window, type the name of the view/table, highlight it, and press Alt-F1. This will run sp_help, like blachniet suggested.
simple list of column names without any further information.
SELECT COLUMN_NAME FROM TABLENAME.INFORMATION_SCHEMA.COLUMNS;
Replace TABLENAME with your tables name.

How to find which views are using a certain table in SQL Server (2008)?

I have to add a few columns to a table and I also need to add these columns to all the views that use this table.
Is it possible to get a list of all the views in a database that use a certain table?
This should do it:
SELECT *
FROM INFORMATION_SCHEMA.VIEWS
WHERE VIEW_DEFINITION like '%YourTableName%'
To find table dependencies you can use the sys.sql_expression_dependencies catalog view:
SELECT
referencing_object_name = o.name,
referencing_object_type_desc = o.type_desc,
referenced_object_name = referenced_entity_name,
referenced_object_type_desc =so1.type_desc
FROM sys.sql_expression_dependencies sed
INNER JOIN sys.views o ON sed.referencing_id = o.object_id
LEFT OUTER JOIN sys.views so1 ON sed.referenced_id =so1.object_id
WHERE referenced_entity_name = 'Person'
You can also try out ApexSQL Search a free SSMS and VS add-in that also has the View Dependencies feature. The View Dependencies feature has the ability to visualize all SQL database objects’ relationships, including those between encrypted and system objects, SQL server 2012 specific objects, and objects stored in databases encrypted with Transparent Data Encryption (TDE)
Disclaimer: I work for ApexSQL as a Support Engineer
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??
I find this works better:
SELECT type, *
FROM sys.objects
WHERE OBJECT_DEFINITION(object_id) LIKE '%' + #ObjectName + '%'
AND type IN ('V')
ORDER BY name
Filtering VIEW_DEFINTION inside INFORMATION_SCHEMA.VIEWS is giving me quite a few false positives.
SELECT VIEW_NAME
FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE
WHERE TABLE_NAME = 'Your Table'
select your table -> view dependencies -> Objects that depend on
Simplest way to find used view or stored procedure for the tableName using below query -
exec dbo.dbsearch 'Your_Table_Name'

SQL script to change all table references in all stored procedures

I have created a new database with copies of existing tables but changed the names of these tables, is there a SQL script that I can run (maybe using SysObjects) to change all references to these tables in all stored procedures?
DO NOT RELY ON INFORMATION_SCHEMA.ROUTINES because ROUTINE_DEFINITION is only nvarchar(4000). You need to sys.sql_modules where definition is nvarchar(max)
try any of these to find the procedure that you need to modify:
SELECT DISTINCT
LEFT(s.name+'.'+o.name, 100) AS Object_Name,o.type_desc --, m.definition
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 '%'+#SearchValue+'%'
ORDER BY 1
SELECT
OBJECT_SCHEMA_NAME(m.object_id)+'.'+OBJECT_NAME(m.object_id) --, m.definition
FROM sys.sql_modules m
WHERE m.definition like '%whatever%'
SELECT
OBJECT_SCHEMA_NAME(m.object_id)+'.'+OBJECT_NAME(m.object_id), o.type_desc
--,m.definition
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id=o.object_id
WHERE m.definition like '%whatever%'
you can uncomment m.definition to list out the content, but I find it better to just ID all the procedures and then review them manually, because you don't want to run UPDATE commands on the system tables. Script out the necessary procedures, make the changes (search/replace or manually), and then run the scripts!!!
No.
I believe SQL Refactor from Redgate has this functionality. Otherwise you could script out all objects and either manually or via code do a search and replace.
SQL Server 2005 also has support for synonyms that might be of some help.
Here is a chunk of SQL that you could use to retrieve the definition of stored procedures that match a certain search criteria. You could simply change it to do a search and replace like Martin had suggested.
Simply change '%TABLE_NAME%' to your search criteria or the table name you would like to change.
SELECT ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%TABLE_NAME%' AND ROUTINE_TYPE='PROCEDURE'
If it's short term (like a testing database), the easier solution may be to make a VIEW for each table that you changed, using the old name. For instance, if you changed the table tests to tests_new you can do:
CREATE VIEW dbo.tests
AS
SELECT * FROM dbo.tests_new
All your procedures will that reference dbo.tests will actually look at the data in dbo.tests_new.
This is a very very bad idea if this will be a permanent/production DB, as it just adds a layer of obfuscation to your structure and will make it a nightmare to maintain.
You can't change the table references in sprocs through the system data dictionary - you will have to get the script that creates the stored procedure and change the table names in the script. If you have the scripts this is a simple search and replace for the most part.
If you don't have the scripts you can get the text of the stored procedure scripts from sys.sql_modules, or retrieve it through SSMS.

find the tables has binary data

How to find what are all tables has binary data and display the table name ?
For MySql you want the INFORMATION_SCHEMA COLUMNS table:
http://dev.mysql.com/doc/refman/5.1/en/columns-table.html
If you need to find all of the tables which have binary columns, then you can create a query joining with the INFORMATION_SCHEMA TABLES table:
http://dev.mysql.com/doc/refman/5.1/en/tables-table.html
That depends a lot on what database you are using. Many databases (at least MySQL and PostgreSQL, maybe all) has a database called information_schema (or something similar). This is a database describing the structure of your databases along with all tables, their fields and what types of data the fields hold. So this would be a good starting point.
I'd need to know which database, but this (or something very similar) should work on Oracle:
select *
from all_tab_columns
where data_type in ('BLOB', 'RAW')
;
you need to select the system tables (in msssql 2000 - syscolumns) or system management views (in mssql 2005 or 2008 - sys.columns) to find the columns with system_type_id you need to find, and then find the corresponding table joining sys.columns and sys.objects by object_id field.
Can you ask the DBA or the DB-developper?
if no, what DB (Oracle, MySql, Microsoft, other?) are you using ..
EDITED for MySQL DB
Use
select table_schema
, table_name
, column_name
, data_type
from information_schema
where data_type like '%blob%'
or data_type in ('binary','varbinary')