How to copy and rename a VIEW/SP programmatically in SQL Server? - sql

I know you can right-click on the selected VIEW/SP and select CREATE-TO, and you can just copy the generated script. But this has to be done via a SQL Client.
What I wish to do is that whenever there is an update on the VIEW/SP by my vendor, I would like to perform the backup of the affected VIEW/SP before running the ALTER VIEW/SP command from my vendor. I wish to do this using script rather than human interface so as to reduce the risk of human errors.
Can anyone help?

This should get you started.
DECLARE #SQL VARCHAR(MAX)
SET #SQL = ( SELECT Routine_Definition
FROM ( SELECT Routine_Catalog, Routine_Schema, Routine_Name, Routine_Definition
FROM INFORMATION_SCHEMA.ROUTINES
WHERE Routine_type = 'PROCEDURE'
UNION ALL
SELECT Table_Catalog, Table_Schema, Table_Name, View_Definition
FROM INFORMATION_SCHEMA.VIEWS
) def
WHERE Routine_Catalog = 'YourDatabase'
AND Routine_Schema = 'YourSchema'
AND Routine_Name = 'YourView/SP'
)
IF #SQL IS NULL
RETURN
EXEC SP_RENAME 'YourDatabase.YourSchema.YourView/SP', 'NewName', 'OBJECT'
EXEC (#sql)

Following is the link where you can find how to create/alter/delete Stored procedure using C# code
You can create front end form(GUI) in C# or your desired technology and in in this form
you vendor enter the detail of stored procedures.
http://msdn.microsoft.com/en-us/library/ms162190.aspx
Following are the scripts that you run in Database to find the detail of changes/Created stored procedures
SELECT name 'Alterd Procedures'
FROM sys.objects
WHERE type = 'P'
AND DATEDIFF(D,modify_date, GETDATE()) < 5
SELECT name 'Created Procedures'
FROM sys.objects
WHERE type = 'P'
AND DATEDIFF(D,create_date, GETDATE()) < 5
5 is the no of days, you can change this according to your need
you can change 'P' to 'V' for views

Related

Must pass parameter number 4 and subsequent parameter as '#name =value'

I've got the following stored procedure that runs perfectly in SSMS.
Create Store Proc MyTT
SELECT
MAX(TableName) as TableName,
aco_code,acc_code,
ctr_id,cte_id,usr_code,
-- convert(datetime,convert(varchar,current_timestamp,112),112)
Cast(DATEPART(hour,current_timestamp) as varchar(3))+':'+ CAST(DATEPART(minute,current_timestamp) as varchar(3))as [Time]
INTO #AB
FROM
(
SELECT 'TM_ACO_Account_Comment'as TableName,
a.aco_code,
a.acc_code,
a.ctr_id,
a.cte_id,
a.usr_code
FROM
TM_ACO_Account_Comment a with(NOLOCK)
UNION ALL
SELECT 'TM_ACO_Account_Comment'as TableName,
b.aco_code,
b.acc_code,
b.ctr_id,
b.cte_id,
b.usr_code
FROM
[172.17.14.77].[IS_ND_BLAKE].[dbo].[TM_ACO_Account_Comment] b with(NOLOCK)
)zzz
GROUP BY aco_code,
acc_code,
ctr_id,
cte_id,
usr_code
HAVING COUNT(*) = 1
ORDER BY
aco_code
SELECT *
FROM
#AB
DROP TABLE #AB
But when I try to include the procedure in a query to send out mail, I get the following error:
Must pass parameter number 4
My Mail Query looks like this.
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'DBMail',
#recipients = 'mitch#domain.com',
#query = 'exec SP,`MYTT`
#execute_query_database = 'MYDB',
#subject = 'Work Order Count',
#attach_query_result_as_file = 1 ;
In your EXEC msdb.dbo.sp_send_dbmail command, you seem to have not closed the string literal in this line properly:
#query = 'exec SP,`MYTT`
It is missing a closing ', as well as a comma to separate this argument from the next one:
#query = 'exec SP,`MYTT`',
However, the passed query itself looks a bit strange. Your stored procedure is called MyTT and if you meant it to be called in the query you are passing to msdb.dbo.sp_send_dbmail, you specified the exec statement incorrectly. It should probably be simply like this:
#query = 'exec MyTT',
Although it might be a good idea to specify the database and the schema too:
#query = 'exec YourDBName.YourSchema.MyTT',
I have slightly corrected the name proper to match the one in your definition exactly. If your server's default collation is case-insensitive (which is likely), that may be unnecessary, but it would not harm to be consistent in such matters.

Search of table names

I use the following to search for strings within the stored procedures of a specific database:
USE DBname
SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%xxx%'
Is it easy to amend the above so that it searches Table names in a specific db "DBname" ?
I'm using this and works fine
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%%'
select name
from DBname.sys.tables
where name like '%xxx%'
and is_ms_shipped = 0; -- << comment out if you really want to see them
If you want to look in all tables in all Databases server-wide and get output you can make use of the undocumented sp_MSforeachdb procedure:
sp_MSforeachdb 'SELECT "?" AS DB, * FROM [?].sys.tables WHERE name like ''%Table_Names%'''
You can also use the Filter button to filter tables with a certain string in it.
You can do the same with stored procedures and views.
I am assuming you want to pass the database name as a parameter and not just run:
SELECT *
FROM DBName.sys.tables
WHERE Name LIKE '%XXX%'
If so, you could use dynamic SQL to add the dbname to the query:
DECLARE #DBName NVARCHAR(200) = 'YourDBName',
#TableName NVARCHAR(200) = 'SomeString';
IF NOT EXISTS (SELECT 1 FROM master.sys.databases WHERE Name = #DBName)
BEGIN
PRINT 'DATABASE NOT FOUND';
RETURN;
END;
DECLARE #SQL NVARCHAR(MAX) = ' SELECT Name
FROM ' + QUOTENAME(#DBName) + '.sys.tables
WHERE Name LIKE ''%'' + #Table + ''%''';
EXECUTE SP_EXECUTESQL #SQL, N'#Table NVARCHAR(200)', #TableName;
If you prefer case-insensitive searching:
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME ILIKE '%%'
or
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE Lower(TABLE_NAME) LIKE Lower('%%')
Adding on to #[RichardTheKiwi]'s answer.
Whenever I search for a list of tables, in general I want to select from all of them or delete them. Below is a script that generates those scripts for you.
The generated select script also adds a tableName column so you know what table you're looking at:
select 'select ''' + name + ''' as TableName, * from ' + name as SelectTable,
'delete from ' + name as DeleteTable
from sys.tables
where name like '%xxxx%'
and is_ms_shipped = 0;
you can also use the show command.
show tables like '%tableName%'
I want to post a simple solution for every schema you've got. If you are using MySQL DB, you can simply get from your schema all the table's name and add the WHERE-LIKE condition on it. You also could do it with the usual command line as follows:
SHOW TABLES WHERE tables_in_<your_shcema_name> LIKE '%<table_partial_name>%';
where tables_in_<your_shcema_name> returns the column's name of SHOW TABLES command.
You can use below :
Select * from sys.tables where name like '%yourtablename%'
This will working fine....
SELECT * FROM sys.TABLES
WHERE name LIKE '%%'

Find a database with a particular table OR Find a table in every database of SQL Server

I have a SQL Server with hundreds of databases and each database having hundreds of tables.
Now I would like to find where in these databases is a table that I am looking for.
I could find if a table existed in individual database using
use myDatabase
select * from sys.tables where name = 'mytable'
GO
but using this means I have to manually change the database for hundreds of times .
I would like to find the database name only.
Is there a way out ?
Okay, if you're just wanting to find each database that contains a particular table, and aren't going to be querying the table, then you can just do:
create table #t (
DBName sysname not null
)
go
exec sp_MSforeachdb 'use [?]; if OBJECT_ID(''dbo.mytable'') is not null insert into #t (DBName) select ''?'''
go
select * from #t
go
drop table #t
(If you're not using multiple schemas in your databases, you won't need to specify dbo in the OBJECT_ID call, otherwise I use it to avoid finding tables in the wrong schema)
This should do what you are looking for:
EXEC sp_MSforeachdb "use [?];select * from sys.tables where name='TableName' "
To include the name of the current database in the output use:
EXEC sp_MSforeachdb "use [?];select '[?]' as DatabaseName, * from sys.tables where name='TableName' "
SELECT DISTINCT DB_NAME(database_id)
FROM [sys].[dm_db_index_operational_stats](NULL,NULL,NULL,NULL)
WHERE OBJECT_NAME(object_id,database_id) = 'mytable'
I know this is an old thread but was high on my google search. So I wanted to contribute for others looking to find a database with a certain table in it. These apply to SQL Server 2008 - Current.
I started with this, which worked for my SA level login, but gave me issues with users that did not have permissions to all databases.
SELECT name
FROM sys.databases
WHERE CASE
WHEN state_desc = 'ONLINE' THEN OBJECT_ID( QUOTENAME( name ) + '.[dbo].[mytablename]','U' )
END IS NOT NULL;
But ended up with this adding the HAS_DBACCESS(name) = 1 in restriction so that the query would not fail with a security error.
SELECT name
FROM sys.databases
WHERE HAS_DBACCESS(name) = 1 and
CASE
WHEN state_desc = 'ONLINE' THEN OBJECT_ID( QUOTENAME( name ) + '.[dbo].[mytablename]','U' )
END IS NOT NULL;
exec sp_msforeachdb #command1='
USE ?;
select * from sys.tables where name = ''CLIENTS'''
this is also one of the way, similar with solution of #Jonathan :
exec sp_MSforeachdb 'SELECT "?" AS DB, * FROM [?].sys.tables WHERE name like ''%YourTableName%'''
exec 'select ''?'', name from [?].sys.tables where name = ''yourTable'''

Find stored procedure by name

Is there any way I can find in SQL Server Management Studio stored procedure by name or by part of the name? (on active database context)
Thanks for help
You can use:
select *
from
sys.procedures
where
name like '%name_of_proc%'
if you need the code you can look in the syscomments table
select text
from
syscomments c
inner join sys.procedures p on p.object_id = c.object_id
where
p.name like '%name_of_proc%'
Edit Update:
you can can also use the ansi standard version
SELECT *
FROM
INFORMATION_SCHEMA.ROUTINES
WHERE
ROUTINE_NAME LIKE '%name_of_proc%'
Assuming you're in the Object Explorer Details (F7) showing the list of Stored Procedures, click the Filters button and enter the name (or partial name).
This will work for tables and views (among other things) as well, not just sprocs:
SELECT
'[' + s.name + '].[' + o.Name + ']',
o.type_desc
FROM
sys.objects o
JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE
o.name = 'CreateAllTheThings' -- if you are certain of the exact name
OR o.name LIKE '%CreateAllThe%' -- if you are not so certain
It also gives you the schema name which will be useful in any non-trivial database (e.g. one where you need a query to find a stored procedure by name).
When I have a Store Procedure name, and do not know which database it belongs to, I use the following -
Use [master]
GO
DECLARE #dbname VARCHAR(50)
DECLARE #statement NVARCHAR(max)
DECLARE db_cursor CURSOR
LOCAL FAST_FORWARD
FOR
--Status 48 (mirrored db)
SELECT name FROM MASTER.dbo.sysdatabases WHERE STATUS NOT LIKE 48 AND name NOT IN ('master','model','msdb','tempdb','distribution')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #dbname
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #statement = 'SELECT * FROM ['+#dbname+'].INFORMATION_SCHEMA.ROUTINES WHERE [ROUTINE_NAME] LIKE ''%name_of_proc%'''+';'
print #statement
EXEC sp_executesql #statement
FETCH NEXT FROM db_cursor INTO #dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor
You can use this query:
SELECT
ROUTINE_CATALOG AS DatabaseName ,
ROUTINE_SCHEMA AS SchemaName,
SPECIFIC_NAME AS SPName ,
ROUTINE_DEFINITION AS SPBody ,
CREATED AS CreatedDate,
LAST_ALTERED AS LastModificationDate
FROM INFORMATION_SCHEMA.ROUTINES
WHERE
(ROUTINE_DEFINITION LIKE '%%')
AND
(ROUTINE_TYPE='PROCEDURE')
AND
(SPECIFIC_NAME LIKE '%AssessmentToolDegreeDel')
As you can see, you can do search inside the body of Stored Procedure also.
For SQL Server version 9.0 (2005), you can use the code below:
select *
from
syscomments c
inner join sys.procedures p on p.object_id = c.id
where
p.name like '%usp_ConnectionsCount%';
Option 1: In SSMS go to View > Object Explorer Details or press F7. Use the Search box. Finally in the displayed list right click and select Synchronize to find the object in the Object Explorer tree.
Option 2: Install an Add-On like dbForge Search. Right click on the displayed list and select Find in Object Explorer.
Very neat trick I stumble upon trying some SQL injection, in object explorer in the search box just use your percentage characters, and this will search EVERYTHING stored procedures, functions, views, tables, schema, indexes...I tired of thinking of more :)
Search Pattern

SQL Server - Return SCHEMA for sysobjects

How to I get the SCHEMA when doing a select on sysobjects?
I am modifing a stored procedure called SearchObjectsForText which returns only the Name but I would also like to include the SCHEMA.
Right now it is doing something similar to this:
SELECT DISTINCT name
FROM sysobjects
I would like to know what tables need to be joined to return the SCHEME for each 'name'.
If you mean SQL Server 2005 or higher, use sys.objects instead of sysobjects:
SELECT sys.objects.name, sys.schemas.name AS schema_name
FROM sys.objects
INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id
2005 introduced schemas. up to 2000, users equaled schemas. The same query for SQL Server 2000:
SELECT sysusers.name AS OwnerName, sysobjects.name
FROM sysobjects
INNER JOIN sysusers ON sysobjects.uid = sysusers.uid
On Sql Server 2005 (and above) you can use the sys.objects view:
select
name as ObjectName,
schema_Name(schema_id) as SchemaName
from
sys.objects
In Sql Server 2000 (and below), "schema" had a different conceptual meaning. Note from MSDN:
In earlier releases of SQL Server, databases could contain an entity called a "schema", but that entity was effectively a database user. SQL Server 2005 is the first release of SQL Server in which a schema is both a container and a namespace.
Could you use the Information_Schema view(s) instead?
SELECT DISTINCT table_name, table_schema
FROM INFORMATION_SCHEMA.TABLES
According to the MSDN page (for SQL Server 2008 and above),
Do not use INFORMATION_SCHEMA views to determine the schema of an object. The only reliable way to find the schema of a object is to query the sys.objects catalog view.
However, it seems that they're probably referring to an issue where you have a table name and are trying to find its schema, which wouldn't work if there were multiple tables with the same name (in different schemas). If you're querying for multiple results (not just trying to find the schema for a specific table), then it should be fine.
I would favor using the more focused "sys" views - sys.procedures instead of sys.objects. You'll need to join it with the sys.schemas view to get schema name and such.
select
p.name,
s.name 'Schema',
p.type_desc, p.create_date, p.modify_date
from
sys.procedures p
inner join
sys.schemas s ON p.schema_id = s.schema_id
I would start to get away from using "sysobjects" since Microsoft clearly states in Books Online that "sysobjects" is subject to removal in a future release:
This SQL Server 2000 system table is included as a view for backward compatibility. We recommend that you use the current SQL Server system views instead. To find the equivalent system view or views, see Mapping SQL Server 2000 System Tables to SQL Server 2005 System Views. This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.
Marc
Just to repeat what's already been suggested here, here's what I've used, to get a list of Tables, Stored Procedures, Views and Functions in my database:
SELECT schema_Name(schema_id) as SchemaName,
[name], -- Name of the Table, Stored Procedure or Function
[type] -- 'V' for Views, 'U' for Table, 'P' for Stored Procedure, 'FN' for function
FROM sys.objects
WHERE [type_desc] IN ( 'USER_TABLE', 'SQL_STORED_PROCEDURE', 'VIEW', 'SQL_SCALAR_FUNCTION')
AND [name] NOT LIKE 'sp_%'
AND [name] NOT LIKE 'fn_%'
ORDER BY 3 DESC, -- type first
1 ASC, -- then schema
2 ASC -- then function/table name
...and here's what our good friend Northwind would return...
In SQL 200:
select DISTINCT
name as ObjectName,
USER_NAME(uid) as SchemaName
from
sysobjects
In earlier releases of SQL Server, databases could contain an entity called a "schema", but that entity was effectively a database user.
Have included an option to delete all objects starting with certain prefix and optionally from certain schema.
By the way, I added extra query to get all types which are not stored on sysobjects by default.
I have uploaded entire sample script to GitHub:
DropAll_Dnn_Objects.sql
Part 1: Temporary Stored Procedure:
IF OBJECT_ID('_temp_DropAllDnnObjects') IS NOT NULL
DROP PROCEDURE _temp_DropAllDnnObjects;
GO
CREATE PROCEDURE _temp_DropAllDnnObjects
#object_prefix NVARCHAR(30),
#schema_name sysname = NULL
AS
BEGIN
DECLARE #sname sysname, #name sysname, #type NVARCHAR(30)
DECLARE #object_type NVARCHAR(255), #sql NVARCHAR(2000), #count INT = 0
DECLARE curs CURSOR FOR
SELECT sname, [name], xtype
FROM (
SELECT SCHEMA_NAME(schema_id) as sname, [name], [type] as xtype
FROM sys.objects
WHERE [type] IN ('U', 'P', 'FN', 'IF', 'TF', 'V', 'TR')
AND name LIKE #object_prefix + '%'
AND (#schema_name IS NULL OR schema_id = SCHEMA_ID(#schema_name))
UNION ALL
SELECT SCHEMA_NAME(schema_id) as sname, [name], 'TYPE' as xtype
FROM sys.types
WHERE is_user_defined = 1
AND [name] LIKE #object_prefix + '%'
AND (#schema_name IS NULL OR schema_id = SCHEMA_ID(#schema_name))
) a
ORDER BY CASE xtype
WHEN 'P' THEN 1
WHEN 'FN' THEN 2
WHEN 'IF' THEN 3
WHEN 'TF' THEN 4
WHEN 'TR' THEN 5
WHEN 'V' THEN 6
WHEN 'U' THEN 7
WHEN 'TYPE' THEN 8
ELSE 9
END, name
OPEN curs;
FETCH NEXT FROM curs INTO #sname, #name, #type;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #count = #count + 1
-- Configuration point 2
SET #object_type = CASE #type
WHEN 'P' THEN 'PROCEDURE'
WHEN 'FN' THEN 'FUNCTION'
WHEN 'IF' THEN 'FUNCTION'
WHEN 'TF' THEN 'FUNCTION'
WHEN 'TR' THEN 'TRIGGER'
WHEN 'V' THEN 'VIEW'
WHEN 'U' THEN 'TABLE'
WHEN 'TYPE' THEN 'TYPE'
END
SET #sql = REPLACE(REPLACE(REPLACE('DROP <TYPE> [<SCHEMA>].[<NAME>];',
'<TYPE>', #object_type),
'<SCHEMA>', #sname),
'<NAME>', #name)
BEGIN TRY
PRINT #sql
EXEC(#sql)
END TRY
BEGIN CATCH
PRINT 'ERROR: ' + ERROR_MESSAGE()
END CATCH
FETCH NEXT FROM curs INTO #sname, #name, #type;
END;
PRINT CONCAT('Objects Found: ', #Count)
PRINT ''
PRINT '------------------------------------------------------'
PRINT ''
CLOSE curs;
DEALLOCATE curs;
RETURN #Count
END;
GO
It will continue on errors (and display the error message). It will return a count of all objects found.
Part 2: Call Stored Procedure with parameters:
You can create a WHILE loop in order to run the command until no object is left (dependencies), as follows:
DECLARE #count INT = 1
WHILE #count > 0 EXEC #count = _temp_DropAllDnnObjects 'dnn';
SET #count = 1
WHILE #count > 0 EXEC #count = _temp_DropAllDnnObjects 'aspnet';
SET #count = 1
WHILE #count > 0 EXEC #count = _temp_DropAllDnnObjects 'vw_aspnet';
GO
Part 3: Finally, get rid of the procedure:
IF OBJECT_ID('_temp_DropAllDnnObjects') IS NOT NULL
DROP PROCEDURE _temp_DropAllDnnObjects;
GO
Instead of a view, why not use this to populate a temporary table you can use?
This is the solution I use in stored procedures
This is the best way to get a schema dynamically and add it to the different tables within a database in order to get other information dynamically
select #sql = 'insert #tables SELECT ''[''+SCHEMA_NAME(schema_id)+''.''+name+'']'' AS SchemaTable FROM sys.tables'
exec (#sql)
of course #tables is a dynamic table in the stored procedure