Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Stored procedure to loop through databases

Author  Topic 

Stevan23
Starting Member

15 Posts

Posted - 2015-03-16 : 07:32:36
Hi all,

We're running SQL Server 2008 and have run into a bit of a situation.

We have 5 databases all with the same tables and we are trying to create a query that will loop through the different databases and output the results per company database. I originally did a cursor, but my boss wants the query to be in a more readable format:

His ideal wish would be the query in a stored procedure and the cursor to create the input parameter for the stored procedure for the different databases. Not sure if this is possible?

I've tried looking through some forums and googling some possibilities but can't seem to make any sense of them.

Any help would be greatly appreciated.

Many thanks,
Stevan23

use master

declare @dbname varchar(100)
,@sql varchar(max)


create table #TempDBs (
dbname nvarchar(100)
, Orig_Jnl int
, BaseRef int
, Posting_Date date
, Memo nvarchar(100)
, Ref1 nvarchar(100)
, Ref2 nvarchar(100)
, Jnl_LocTotal float
, Jnl_FcTotal float
, Jnl_SysTotal float
, TransRate float
, PostingMonth int
, PostingYear int
, PostingFinYear int
, PostingFinMth int
, GFAcctGrp nvarchar(100)
, GFAcctName nvarchar(100)
, FthAcctGrp nvarchar(100)
, FthAcctName nvarchar(100)
, AcctGrp nvarchar(100)
, FormatCode nvarchar(100)
, AcctName nvarchar(100)
, LineTotal float
, FCDebit float
, FCCredit float
, ContraAct nvarchar(100)
, LineMemo nvarchar(100)
, TransType int
, ProfitCode nvarchar(10)
, Line_ID int
, BPName nvarchar(100)
, Dscription nvarchar(100)
)

declare db_cur cursor for
SELECT name
FROM master.dbo.sysdatabases where dbid in ('8','18','19','24','25','30')

open db_cur
fetch next from db_cur into @dbname

while @@FETCH_STATUS = 0
begin

set @sql= '
DECLARE @FromDate date
DECLARE @ToDate date

SET @FromDate = ''20150201''
SET @ToDate = ''20150228''

insert into #TempDbs(
dbname,
Orig_Jnl,
BaseRef,
Posting_Date,
Memo,
Ref1,
Ref2,
Jnl_LocTotal,
Jnl_FcTotal,
Jnl_SysTotal,
TransRate,
PostingMonth,
PostingYear,
PostingFinYear,
PostingFinMth,
GFAcctGrp,
GFAcctName,
FthAcctGrp,
FthAcctName,
AcctGrp,
FormatCode,
AcctName,
LineTotal,
FCDebit,
FCCredit,
ContraAct,
LineMemo,
TransType,
ProfitCode,
Line_ID,
BPName,
Dscription
)
select a.DbName, a.Orig_Jnl, a.BaseRef, a.Posting_Date, a.Memo, a.Ref1, a.Ref2, a.Jnl_LocTotal, a.Jnl_FcTotal, a.Jnl_SysTotal, a.TransRate, a.PostingMonth, a.PostingYear, a.PostingFinYear,
a.PostingFinMth, a.GFAcctGrp, a.GFAcctName, a.FthAcctGrp, a.FthAcctName, a.AcctGrp, a.FormatCode, a.AcctName, a.LineTotal, a.FCDebit, a.FCCredit, a.ContraAct, a.LineMemo, a.TransType,
a.ProfitCode, a.Line_ID, a.BPName, a.Dscription
FROM (SELECT DISTINCT '''+@dbname+''' DbName,
t0.TransId, t0.TransType AS Orig_Jnl, t0.BaseRef, t0.RefDate AS Posting_Date, t0.Memo, t0.Ref1, t0.Ref2, t0.LocTotal AS Jnl_LocTotal, t0.FcTotal AS Jnl_FcTotal,
t0.SysTotal AS Jnl_SysTotal, t0.TransRate, MONTH(t0.RefDate) AS PostingMonth, YEAR(t0.RefDate) AS PostingYear, (CASE WHEN Month(t0.RefDate)
<= 6 THEN Year(t0.RefDate) ELSE Year(t0.RefDate) + 1 END) AS PostingFinYear, (CASE WHEN Month(t0.RefDate) <= 6 THEN Month(t0.RefDate)
+ 6 ELSE Month(t0.RefDate) - 6 END) AS PostingFinMth, t4.FatherNum As GFAcctGrp, t4.AcctName As GFAcctName, t3.FatherNum As FthAcctGrp,
t3.AcctName As FthAcctName, t2.FatherNum As AcctGrp, t2.FormatCode, t2.AcctName,
(CASE
when t1.TransType = ''13'' then t31.LineTotal
when t1.TransType = ''14'' then t32.LineTotal*-1
when t1.TransType = ''18'' then t36.LineTotal
when t1.TransType = ''19'' then t37.LineTotal*-1
else t1.Debit - t1.Credit
End) As LineTotal,
t1.FCDebit, t1.FCCredit, t1.ContraAct, t1.LineMemo, t1.TransType,
t1.ProfitCode, t1.Line_ID,
isnull(CASE
when t1.TransType = ''13'' then t8.CardName
when t1.TransType = ''14'' then t9.CardName
when t1.TransType = ''18'' then t13.CardName
when t1.TransType = ''19'' then t14.CardName
End,'''') As BPName,
isnull(CASE
when t1.TransType = ''13'' then t31.Dscription
when t1.TransType = ''14'' then t32.Dscription
when t1.TransType = ''18'' then t36.Dscription
when t1.TransType = ''19'' then t37.Dscription
when t1.TransType = ''30'' then ''Journal Entry''
End,'''') As Dscription
FROM '+@dbname+'.dbo.OJDT t0
INNER JOIN '+@dbname+'.dbo.JDT1 t1 ON t0.TransId = t1.TransId
LEFT JOIN '+@dbname+'.dbo.OACT t2 ON t1.Account = t2.AcctCode
LEFT JOIN '+@dbname+'.dbo.OACT t3 ON t2.FatherNum = t3.AcctCode
LEFT JOIN '+@dbname+'.dbo.OACT t4 ON t3.FatherNum = t4.AcctCode
LEFT JOIN '+@dbname+'.dbo.OINV t8 ON t1.BaseRef = t8.DocNum and t1.TransType = ''13''
LEFT JOIN '+@dbname+'.dbo.INV1 t31 ON t8.DocEntry = t31.DocEntry and t1.Account = t31.AcctCode and t31.TaxOnly = ''N'' and t1.ProfitCode = t31.OcrCode
LEFT JOIN '+@dbname+'.dbo.ORIN t9 ON t1.BaseRef = t9.DocNum and t1.TransType = ''14''
LEFT JOIN '+@dbname+'.dbo.RIN1 t32 ON t9.DocEntry = t32.DocEntry and t1.Account = t32.AcctCode and t32.TaxOnly = ''N'' and t1.ProfitCode = t32.OcrCode
LEFT JOIN '+@dbname+'.dbo.OPCH t13 ON t1.BaseRef = t13.DocNum and t1.TransType = ''18''
LEFT JOIN '+@dbname+'.dbo.PCH1 t36 ON t13.DocEntry = t36.DocEntry and t1.Account = t36.AcctCode and t36.TaxOnly = ''N'' and t1.ProfitCode = t36.OcrCode and isnull(t36.Project,'''') = isnull(t1.Project,'''')
LEFT JOIN '+@dbname+'.dbo.ORPC t14 ON t1.BaseRef = t14.DocNum and t1.TransType = ''19''
LEFT JOIN '+@dbname+'.dbo.RPC1 t37 ON t14.DocEntry = t37.DocEntry and t1.Account = t37.AcctCode and t37.TaxOnly = ''N'' and t1.ProfitCode = t37.OcrCode
LEFT JOIN '+@dbname+'.dbo.OVPM t18 ON t1.BaseRef = t18.DocNum and t1.TransType = ''46''
WHERE t1.RefDate >= @FromDate and t1.RefDate <= @ToDate and t1.TransType in (''13'',''14'',''18'',''19'',''30'',''46'')
) a
ORDER BY a.AcctName, a.ProfitCode'

exec(@sql)

fetch next from db_cur into @dbname

end

close db_cur
deallocate db_cur

select * from #TempDBs order by DbName

drop table #TempDBs

James K
Master Smack Fu Yak Hacker

3873 Posts

Posted - 2015-03-16 : 08:53:03
Since you have databases with identical schema, one approach would be to create the stored procedure in each database and then use the (undocumented) stored proc sp_MSforeachdb
EXEC master.sys.sp_MSforeachdb 'USE [?]; EXEC yourStoredProc;'

Go to Top of Page

Stevan23
Starting Member

15 Posts

Posted - 2015-03-16 : 16:04:59
Hi James K,

Thanks for that, when executing the MSforeachdb, are you able to pass date parameters to the stored procedures?

Would this also append the one result set or would each result set be independent?

Thanks,
Stevan23
Go to Top of Page

James K
Master Smack Fu Yak Hacker

3873 Posts

Posted - 2015-03-17 : 12:08:38
Steven, You can pass parameters to the stored proc - see some examples here: http://www.mssqltips.com/sqlservertip/1414/run-same-command-on-all-sql-server-databases-without-cursors/ or other places that you can look up on google.

There will be one result set for each database.
Go to Top of Page

Stevan23
Starting Member

15 Posts

Posted - 2015-03-20 : 05:32:32
Thanks James K,

We will give it a go on Monday.
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2015-03-20 : 07:37:31
Rather than using dynamic SQL and Cursors I would have an SProc in each database and then call that from the central database (for whichever database(s) are needed according to the criteria supplied [by the user presumably]). The data returned by those databases could then be inserted into a temporary table (or the central Sproc could create a temporary table(s) and each Sproc called could insert into that table(s)), such that the central Sproc could then filter / sort etc. the results.

You could dynamically determine what databases are available, but if you then have the need to make an emergency restore of one of them, to a temporary database, or add a database in future that has nothing to do with this application there is a risk that automatic detection then breaks / misbehaves, so my inclination would be to have a Table of appropriate Database names in the central database - if a new database is added / dropped then a row would need to be inserted / deleted from that table though, which is Something Else To Go Wrong ...
Go to Top of Page

huangchen
Starting Member

37 Posts

Posted - 2015-04-02 : 05:56:42
unspammed
Go to Top of Page

Stevan23
Starting Member

15 Posts

Posted - 2015-04-02 : 19:03:57
Hi James K and Kristen,

We gave a try for what you both suggested - a central stored procedure that can call each one and that worked well. Thanks for the help.

Really appreciate it.

Many thanks,
Stevan23
Go to Top of Page
   

- Advertisement -