I have a table which has 50+ columns but only few columns are getting used. that means when any stored procedure uses that table it only refers 4-5 columns in select/where statements . rest of columns are not getting used . i just want to list down those columns that are actually getting used. one way is finding out the dependencies of a table and then go through every SP and find out which columns are getting used . but in that case i have around 30+ Sp. is there any efficient way to do it.
To use multiple columns in a procedure, you can use a code like below
create procedure sp_sample
#column_names varchar(200)
as
if #column_names='' or #column_nams is null
set #column_names='*'
exec ('select '+#column_name +' from table')
Here are some examples :
exec sp_sample #columnname='id,name'
or
exec sp_sample #columnname='id,name,telphone'
Try this:
select name from syscomments c
join sysobjects o on c.id = o.id
where TEXT like '%table_name%' and TEXT like '%column_name%'
In table_name give you table name, in column_name give the column for which you want to chck the procedure dependencies.You will get the stored procedure names as output
If you import your database as a database project using the SQL Server Data Tools, you will be able to find all references to a table or column using the "Find All References" context command. What makes this particularly useful is the accuracy: it will even find instances of SELECT * that don't mention the column explicitly, but implicitly refer to it anyway. It will also not be confused by tables or columns with similar names (finding particular instances of ID is otherwise rather problematic).
If all you want to know if a column is referenced at all, you can simply delete it and see if any "unresolved reference" errors appear in the error list -- if yes, then the column is used somewhere.
Related
Having a database with a main table called "MasterTable". Found out that there are some columns in MasterTable that are no longer reasonable (from business purpose). To make everything slimer and easier I'd like to delete those columns.
In case I delete column ABC a view that refers to that column or a stored procedure doing an insert/update might fail when ABC is missing.
For this I'd like to query my database to see all views/procedures that somehow use ABC, before deleting it.
Something like this should help you . But please remember:
It will also give you results where the column might be commented out..
If you use select * in view or procedure it will not be shown in the result
SELECT OBJECT_NAME(OBJECT_ID),definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'YourColumnName' + '%'
We have a table on the SQL Server 2008 which gets populated by various stored procedures. The problem is that the authors of these stored procedures used some poor choice in code and populated this table using the following syntax:
INSERT INTO persistant_table
SELECT *
FROM #temp_table_with_data
Basically they would create a #temp_table_with_data in the script and the columns would be in the same order and with the same name as they are in the persistant_table.
Now I need to add another column to this persistant_table, but if I do that, I will break all the stored procedures.
Is there a way for me to add a column to this table without breaking all the stored procedures? (In the long run, we will change the stored procedures).
Thank you
No I think.select * will pick all columns and column number should match.
I don't think it's big effort to change the line to have particular columns only or select statement to have default value for column or null and then * to store into columns sequentially. But at least 1 line to be changed
The "ALTER TABLE" is a SQL statement that allows you to make datatype changes to a database table (i.e. change datatype as well as Size columns from an existing table).
ALTER TABLE TableName ALTER COLUMN ColumnName NVARCHAR(200)
You cannot do it without affecting old scripts. This is why 'SELECT *' is not good practice. You'd better create new scripts with explicit column names like
SELECT column1, column2 ....
Good day, I am specifically trying to perform a search through my storedprocedures with the aim of finding a procedure that does not contain a cetain word. Example "nolock".
I understand and i successfully achieved this with a query like below.
Select Name as [Procedurees with no nolock] from
database.sys.procedure WHERE (OBJECT_DEFINITION(OBJECT_ID)
NOT LIKE '%myKeyword%' .
The above successfully returned the names of procedures without the keyword in them. However, the stored procedures script are mostly long and may require the use of the keyword more than one time in a single procedure. Example may be after each "FROM TABLE name" i need a key word "with nolock" . I want the search to be perform till the end of the procedure and where exist a "TABLE NAME", a "mykeyword" must follow else return the procedure name among those with no "mykeyword".
Since i have like twelve table names i want to use, i thought i could use CASE like
Select Name as [Procedurees with no nolock] from database.sys.procedure
WHERE (OBJECT_DEFINITION(OBJECT_ID) NOT LIKE '%Mytable NAME , then plus the keyword%'.
This does not look ok for me because i have quite few tables names and it also possible that the table name may appear numerous time in the procedure and may be have the 'keyword' for the first time only. Please is there anyway i can achieve this ? Also sorry for my inability to explain clearly. Any help would be appreciated
Sorry, but your question doesn't really make any sense to me. But I'll try to answer.
Blockquote
because i have quite few tables names and it also possible that the table name may appear numerous time in the procedure
Can't you just use a GROUP BY to restrict the results to one set per table?
Select Name as [Procedurees with no nolock] from database.sys.procedure
WHERE (OBJECT_DEFINITION(OBJECT_ID) NOT LIKE '%Mytable NAME , then plus the keyword%'
GROUP BY database.sys.procedure
If you want to do this for each table in your database, you can use this:
DECLARE #keyword NVARCHAR(20) = 'words'
sp_MSForEachTable 'Select Name as [Procedurees with no nolock] from database.sys.procedure
WHERE (OBJECT_DEFINITION(OBJECT_ID) NOT LIKE ? AND , (OBJECT_DEFINITION(OBJECT_ID) LIKE ''' + #KeyWord + '''
GROUP BY database.sys.procedure'
The ? is replaced by the table name in the stored procedure.
Why don't you turn it around...?
Find the procedures that DO match, and then exclude them ?
select name from sys.procedures
where name not in (select name from sys.procedures WHERE (OBJECT_DEFINITION(OBJECT_ID) LIKE '%blah%'))
I need to create a view, however the data is generated from an application with its own db management for tables which based on column count can create over 7 SQL Server tables for one internal table definition.
The tables all end with ['m' & number], eg devicem1, devicem2 ... devicem10
They all contain logical_name as their primary key, but you can never rely on which table will hold any other column in the internal table!
I need to create a view that joins the tables together as just device so when the application changes it doesn't mess up any stored procs I want to create.
Based on this query:
CREATE VIEW device AS
SELECT *
FROM devicem1 m1, devicem2 m2, devicem3 m3, ... devicem10 m10
WHERE m1.logical_name = m2.logical_name
AND m1.logical_name = m3.logical_name
...
AND m1.logical_name = m10.logical_name
Is there some way to join ten tables where I can ignore the fact that devicem9 & devicem10 may not exist?
With regards to the requirements of a view. The tables referenced MUST exist when the view is created. The SQL engine isn't going to allow you to create a view referencing tables that don't exist.
Considering that a view is just a stored select statement, after it's created the tables can be deleted (as long as schema-binding isn't in play); however any time you call or use the view all referenced tables must exist or it will toss an error.
Also, you CAN change the schema of referenced tables as long as it doesn't remove any fields specifically used in the view but again, if a specific column used by the view is missing any query using the view will fail.
You might have more luck getting away with what your trying to do with some creative table valued functions and dynamic sql. A table valued function is basically just a view that allows parameters and extended logic.
All in all, I would say what your describing sounds a little sketchy though.
I would periodically recreate the view based on the tables that are available.
So, if the application runs every night to create the tables, then after the app runs, check which tables are available and recreate the views.
In the end, you will have to use dynamic sql, doing something like:
declare #sql varchar(max);
select #sql = (select '(select * from '+table_name+') union all'
from information_schema.tables
for xml path (''));
set #sql = left(#sql, len(#sql) - 10);
set #sql = 'create view <whatever> as '+#sql;
exec(#sql);
I have a table which has essentially boolean values in a legacy database. The column names are stored as string values in another table so I need to match the column names of one table to a string value in another table. I know there has to be a way to do this directly with SQL in SQL Server but it is beyond me.
My initial thought was to use PIVOT but it is not enabled by default and enabling it would likely be a difficult process with pushing that change to the Production database. I would prefer to use what is enabled by default.
I am considering using COALESCE to translate the boolean value to the string that value that I need. This will be a manual process.
I think I will also use a table variable to insert the results of the first query into that variable and use those results to do the second query. I still have the problem that the columns are on a single row so I wish I could easily pivot the values to put the column names in the result set as strings. But if I could easily do that I could easily write the query with a sub-select.
Any tips are welcome.
Checkout Sysobjects and SysColumns in SQL Server. They are 2 SQL tables that gives you the names of the tables in your DB and the names of the columns that go with that table.
The system view INFORMATION_SCHEMA.COLUMNS will also give you what you want.
You can build a SQL string and then execute that string as a query. Not the prettiest by any means but I think it would work the way you want it to. You would just use a cursor or while loop to build the string.
If you're comfortable with .Net you could just write your own stored proc in your language of choice and manipulate the data in code instead.
Heres a link to get started
CLR Stored Procedures
I'm not quite sure I understand how your design is currently put together (could you post an example?), but the information_schema.columns view will give you a table containing all the column names as string values. If you join your second table against that I think you'll probably get what you need.
For Example, i have a table STATEtbl having 3 columns and i want to get all the column names of this table as ROW values... i use the below query
Select SC.name as Columns from Syscolumns SC
Join Sysobjects SO On SC.id = SO.Id
where Object_name(SO.Id) = 'STATEtbl'
Result of the query:
Columns
--------
State
StateCode
StateFullName