Skip to content

Commit 04bbf9b

Browse files
authored
Merge pull request #2704 from renegm/dev
#2702 ineachdb proc
2 parents 17442df + 1706654 commit 04bbf9b

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

sp_ineachdb.sql

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,14 @@ BEGIN
101101
@thisdb sysname,
102102
@cr char(2) = CHAR(13) + CHAR(10),
103103
@SQLVersion AS tinyint = (@@microsoftversion / 0x1000000) & 0xff, -- Stores the SQL Server Version Number(8(2000),9(2005),10(2008 & 2008R2),11(2012),12(2014),13(2016),14(2017),15(2019)
104-
@ServerName AS sysname = CONVERT(sysname, SERVERPROPERTY('ServerName')); -- Stores the SQL Server Instance name.
104+
@ServerName AS sysname = CONVERT(sysname, SERVERPROPERTY('ServerName')), -- Stores the SQL Server Instance name.
105+
@NoSpaces nvarchar(20) = N'%[^' + CHAR(9) + CHAR(32) + CHAR(10) + CHAR(13) + N']%'; --Pattern for PATINDEX
106+
105107

106108
CREATE TABLE #ineachdb(id int, name nvarchar(512), is_distributor bit);
107109

110+
111+
/*
108112
-- first, let's limit to only DBs the caller is interested in
109113
IF @database_list > N''
110114
-- comma-separated list of potentially valid/invalid/quoted/unquoted names
@@ -146,7 +150,62 @@ BEGIN
146150
ON names.name = d.name
147151
OPTION (MAXRECURSION 0);
148152
END
153+
*/
149154

155+
/*
156+
@database_list and @exclude_list are are processed at the same time
157+
1)Read the list searching for a comma or [
158+
2)If we find a comma, save the name
159+
3)If we find a [, we begin to accumulate the result until we reach closing ], (jumping over escaped ]]).
160+
4)Finally, tabs, line breaks and spaces are removed from unquoted names
161+
*/
162+
WITH C
163+
AS (SELECT V.SrcList
164+
, CAST('' AS nvarchar(MAX)) AS Name
165+
, V.DBList
166+
, 0 AS InBracket
167+
, 0 AS Quoted
168+
FROM (VALUES ('In', @database_list + ','), ('Out', @exclude_list + ',')) AS V (SrcList, DBList)
169+
UNION ALL
170+
SELECT C.SrcList
171+
, IIF(V.Found = '[', '', SUBSTRING(C.DBList, 1, V.Place - 1))/*remove initial [*/
172+
, STUFF(C.DBList, 1, V.Place, '')
173+
, IIF(V.Found = '[', 1, 0)
174+
, 0
175+
FROM C
176+
CROSS APPLY
177+
( VALUES (PATINDEX('%[,[]%', C.DBList), SUBSTRING(C.DBList, PATINDEX('%[,[]%', C.DBList), 1))) AS V (Place, Found)
178+
WHERE C.DBList > ''
179+
AND C.InBracket = 0
180+
UNION ALL
181+
SELECT C.SrcList
182+
, CONCAT(C.Name, SUBSTRING(C.DBList, 1, V.Place + W.DoubleBracket - 1)) /*Accumulates only one ] if escaped]] or none if end]*/
183+
, STUFF(C.DBList, 1, V.Place + W.DoubleBracket, '')
184+
, W.DoubleBracket
185+
, 1
186+
FROM C
187+
CROSS APPLY (VALUES (CHARINDEX(']', C.DBList))) AS V (Place)
188+
CROSS APPLY (VALUES (IIF(SUBSTRING(C.DBList, V.Place + 1, 1) = ']', 1, 0))) AS W (DoubleBracket)
189+
WHERE C.DBList > ''
190+
AND C.InBracket = 1)
191+
, F
192+
AS (SELECT C.SrcList
193+
, IIF(C.Quoted = 0
194+
,SUBSTRING(C.name, PATINDEX(@NoSpaces, name), DATALENGTH (name)/2 - PATINDEX(@NoSpaces, name) - PATINDEX(@NoSpaces, REVERSE(name))+2)
195+
, C.Name)
196+
AS name
197+
FROM C
198+
WHERE C.InBracket = 0
199+
AND C.Name > '')
200+
SELECT d.database_id
201+
, d.name
202+
, d.is_distributor
203+
FROM sys.databases AS d
204+
WHERE ( EXISTS (SELECT NULL FROM F WHERE F.name = d.name AND F.SrcList = 'In')
205+
OR @database_list IS NULL)
206+
AND NOT EXISTS (SELECT NULL FROM F WHERE F.name = d.name AND F.SrcList = 'Out')
207+
OPTION (MAXRECURSION 0);
208+
;
150209
-- next, let's delete any that *don't* match various criteria passed in
151210
DELETE dbs FROM #ineachdb AS dbs
152211
WHERE (@system_only = 1 AND (id NOT IN (1,2,3,4) AND is_distributor <> 1))
@@ -272,4 +331,3 @@ BEGIN
272331
CLOSE dbs;
273332
DEALLOCATE dbs;
274333
END
275-
GO

0 commit comments

Comments
 (0)