SQL Server: how to use the same procedure in different instances? - sql

I have a stored procedure in a test instance of a sql server (named sql2008test\sql2008_test) and it is located in one database. I would like to use this procedure also in production instance (named sql2008prod\sql2008_prod). Should I copy this procedure into this prod instance or can I modify my procedure somehow to query data from prod instance? The procedure is shown below.
CREATE PROCEDURE dbo.PROC_getDbInfo
AS
SET NOCOUNT ON
TRUNCATE TABLE dbo.dbinfo
EXECUTE sp_msforeachdb 'insert into dbo.dbinfo
select ''?'' as name,
type_desc,
physical_name,
state_desc,
size * 1.0/128 as size_in_mb,
max_size,
growth * 1.0/128 as growth_in_mb,
is_percent_growth,
is_read_only
from [?].sys.database_files'
SELECT ##SERVERNAME as instance_name,
f.name,
d.create_date,
d.compatibility_level,
d.collation_name,
d.user_access_desc,
d.state_desc,
d.recovery_model_desc,
d.page_verify_option_desc,
d.log_reuse_wait_desc,
f.type_desc,
f.physical_name,
f.state_desc,
f.size_in_mb,
f.max_size,
f.growth_in_mb,
f.is_percent_growth,
f.is_read_only
FROM dbo.dbinfo AS f INNER JOIN
sys.databases AS d
ON f.name = d.name
ORDER BY f.name
GO

Run the creation script on your production instance (of course, going through any release processes you have). You could set up linked servers, if you can access your production server from your test instance, but I wouldn't head down that route without a good reason.
BTW, you still have the extra GO statements in that script meaning the sproc will ONLY be created with SET NOCOUNT ON in and won't do anything.

Use Server Objects>Linked Servers so you can select between different instances.

Copy your procedure into Production db.

Related

Check if procedure exists in any database SQL Server

I'd like to know if there is any way to search for a procedure in all the databases of a server (there are only SQL Server databases on that server).
So far I've only found how to find a stored procedure in a certain database with Object_id(), but it would take too long for me to manually search each database by hand. I'd also like to see in which database is the stored procedure applied.
Code I've found so far:
select *
from MyDataBase.sys.objects
where object_id = object_id(N'MyProcedure')
You can try this code
CREATE TABLE #SPs (db_name varchar(100), name varchar(100), object_id int)
EXEC sp_msforeachdb 'USE [?]; INSERT INTO #SPs select ''?'', name, object_id from sys.procedures'
SELECT * FROM #SPs
See also :https://dba.stackexchange.com/questions/130399/script-to-find-the-list-of-stored-procedures-in-all-databases

Create view must be the first statement in the batch

I'm running a set of script files from a .NET based windows application. One of the files has the following script -
IF EXISTS(SELECT * FROM SYS.VIEWS WHERE NAME = 'TP_LEAVEDATA') EXEC SP_RENAME 'TP_LEAVEDATA', 'TP_LEAVEDATA_BKP_EXPORT_TEST1'
CREATE VIEW TP_LEAVEDATA AS
SELECT USERNAME, Dept, LeaveType, LeaveFrom, LeaveUpto FROM LeaveRequest_DATA
When I execute the script I get an error create view must be the first statement in the batch
I can not use GO keyword here because I'm running the scripts through my application, I can not use execute sp_executesql because there are similar files for creating stored procedures as well (which contain single inverted commas inside the query itself). What are the options that i have now ??
PS: The issue doesn't occur with create table command though.
You can use put GO before it:
IF EXISTS(SELECT * FROM SYS.VIEWS WHERE NAME = 'TP_LEAVEDATA') BEGIN
EXEC SP_RENAME 'TP_LEAVEDATA', 'TP_LEAVEDATA_BKP_EXPORT_TEST1' ;
END;
GO
CREATE VIEW TP_LEAVEDATA AS
SELECT USERNAME, Dept, LeaveType, LeaveFrom, LeaveUpto
FROM LeaveRequest_DATA;
Another option is to use dynamic SQL for the view creation.

How to drop and re-create a view on all DB's on a server

I recently had a need to drop and recreate a view across all DB's on a server. Our original script used a cursor which we found to be a bit inefficient. In an earlier qution that I asked on here, the sys.sp_MSforeachdb prcedure was brought to my attention. I was able to use it to do exactly what was needed.
You just have to be mindful of the length of the exec statement. Apparently there is a length limit, the exact scripts I had were throwing errors until I removed all the aliases and bunched up the select statement. I had about 80 columns in it on separate lines.There were some aliases that were necessary, so I obviously left those where needed.
This is the script I ended up with:
USE [Master]
EXECUTE master.sys.sp_MSforeachdb
'USE [?]; IF db_name() NOT IN (''master'',''model'',''msdb'',''ReportServer'',''ReportServerTempDB'',''tempdb'')
BEGIN USE ?
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N''[ViewName]''))
DROP VIEW [ViewName]
EXEC(''
CREATE VIEW ViewName AS
SELECT
db_name() DBName, a.Col1,a.Col2,a.Col3,t.Col1
FROM Activity a
LEFT OUTER JOIN TerminologyCache t ON a.ActivityTypeName = t.TerminologyKeyName
WHERE
a.activityProviderName = ''''Parm1''''
and (ISNULL(t.TerminologyCultureName,''''en-US'''') = ''''en-US'''')
'')
END'

use output of SQL statement as the table to run a query on

I believe what I am attempting to achieve may only be done through the use of Dynamic SQL. However, I have tried a couple of things without success.
I have a table in database DB1 (lets say DB1.dbo.table1, in a MS SQL server) that contains the names of other databases in the server (DB2,DB3, etc). Now, all the dbs listed in that table contain a particular table (lets call it desiredTable) which I want to query. So what I'm looking for is a way of creating a stored procedure/script/whatever that queries DB1.dbotable1 for the other DBs and then run a statement on each of the dbs retrieved, something like:
#DBNAME = select dbName from DB1.dbo.table1
select value1 from #DBNAME.dbo.desiredTable
Is that possible? I'm planning on running the sp/script in various systems DB1.dbo.table1 being a constant.
You need to build a query dinamically and then execute it. Something like this:
DECLARE #MyDynamicQuery VARCHAR(MAX)
DECLARE #MyDynamicDBName VARCHAR(20)
SELECT #MyDynamicDBName = dbName
FROM DB1.dbo.table1
SET #MyDynamicQuery = 'SELECT value1 FROM ' + #MyDynamicDBName + '.dbo.desiredTable'
EXEC(#MyDynamicQuery)
You can use the undocumented stored procedure, sp_MSForEachDB. The usual warnings about using an undocumented stored procedure apply though. Here's an example of how you might use it in your case:
EXEC sp_MSForEachDB 'SELECT value1 FROM ?.dbo.desiredTable'
Notice the use of ? in place of the DB name.
I'm not sure how you would limit it to only DBs in your own table. If I come up with something, then I'll post it here.

SQL Server: using table or #table in stored procedure

I have a stored procedure (see below) which inserts data into a physical table and then joins information with sys.databases. I was thinking that would it be better to not have a physical table for data insertion? Would it be better to fetch these results into a table variable within this procedure? If so, how to do that?
CREATE PROCEDURE dbo.PROC_getDbInfo
AS
SET NOCOUNT ON
GO
TRUNCATE TABLE dbo.dbinfo
GO
EXECUTE sp_msforeachdb 'insert into dbo.dbinfo
select ''?'' as name,
type_desc,
physical_name,
state_desc,
size * 1.0/128 as size_in_mb,
max_size,
growth * 1.0/128 as growth_in_mb,
is_percent_growth,
is_read_only
from [?].sys.database_files'
GO
SELECT ##SERVERNAME as instance_name,
f.name,
d.create_date,
d.compatibility_level,
d.collation_name,
d.user_access_desc,
d.state_desc,
d.recovery_model_desc,
d.page_verify_option_desc,
d.log_reuse_wait_desc,
f.type_desc,
f.physical_name,
f.state_desc,
f.size_in_mb,
f.max_size,
f.growth_in_mb,
f.is_percent_growth,
f.is_read_only
FROM dbo.dbinfo AS f INNER JOIN
sys.databases AS d
ON f.name = d.name
ORDER BY f.name
GO
You'll have to use a table. Either global temp (##) or a normal table.
A table variable will not be in scope for the sp_msforeachdb call if declared for the stored proc, and not visible to the stored proc if declared in sp_msforeachdb
#table is better -- the table is small and the i/o cost will slow it down.
Table variable usage is explained here:
http://msdn.microsoft.com/en-us/library/ms175010.aspx
It basically behaves like a table when it comes to how your script looks - but has very different behaviour under the hood, and if it's small enough should not result in any disc IO.
Also, if the table is only used and then removed during the course of a procedure, this scope limitation becomes a argument for using it.