I have created a SQL script to loop throw databases and create a function (the aim of the function is to convert RTF to Plain Text).
I put the script of the function creation on a variable and try to execute it using the exec command.
I have used While loop and I have put the request on a varchar variable, then, exec #command
but I get this error:
enter image description here
declare #Total as int
select #Total = count(*) from Temp1
declare #counter as int
set #counter = 1
declare #CurrentVal as varchar(max)
declare #command varchar(max)
while (#counter <= #Total)
begin
select #CurrentVal = name from Temp1 where RowId = #counter
set #command=' use '+#CurrentVal+'
GO
CREATE FUNCTION dbo.fnParseTEXTRTF
(
#rtf VARCHAR(max)
)
RETURNS VARCHAR(max)
AS
BEGIN
DECLARE #Stage TABLE
(
Chr CHAR(1),
Pos INT
)
INSERT #Stage
(
Chr,
Pos
)
SELECT SUBSTRING(#rtf, Number, 1),
Number
FROM master..spt_values
WHERE Type = ''p''
AND SUBSTRING(#rtf, Number, 1) IN (''{'', ''}'')
DECLARE #Pos1 INT,
#Pos2 INT
SELECT #Pos1 = MIN(Pos),
#Pos2 = MAX(Pos)
FROM #Stage
DELETE
FROM #Stage
WHERE Pos IN (#Pos1, #Pos2)
WHILE 1 = 1
BEGIN
SELECT TOP 1 #Pos1 = s1.Pos, #Pos2 = s2.Pos
FROM #Stage AS s1
INNER JOIN #Stage AS s2 ON s2.Pos > s1.Pos
WHERE s1.Chr = ''{''
AND s2.Chr = ''}''
ORDER BY s2.Pos - s1.Pos
IF ##ROWCOUNT = 0
BREAK
DELETE
FROM #Stage
WHERE Pos IN (#Pos1, #Pos2)
UPDATE #Stage
SET Pos = Pos - #Pos2 + #Pos1 - 1
WHERE Pos > #Pos2
SET #rtf = STUFF(#rtf, #Pos1, #Pos2 - #Pos1 + 1, '''')
END
SET #Pos1 = PATINDEX(''%\cf[0123456789][0123456789 ]%'', #rtf)
WHILE #Pos1 > 0
SELECT #Pos2 = CHARINDEX('' '', #rtf, #Pos1 + 1), #rtf = STUFF(#rtf, #Pos1, #Pos2 - #Pos1 + 1, ''''), #Pos1 = PATINDEX(''%\cf[0123456789][0123456789 ]%'', #rtf)
SELECT #rtf = REPLACE(#rtf, ''\pard'', ''''), #rtf = REPLACE(#rtf, ''\par'', ''''), #rtf = case when LEN(#rtf)>0 then LEFT(#rtf, LEN(#rtf) - 1) else #rtf end
SELECT #rtf = REPLACE(#rtf, ''\b0 '', ''''), #rtf = REPLACE(#rtf, ''\b '', '''')
SELECT #rtf = STUFF(#rtf, 1, CHARINDEX('' '', #rtf), '''')
RETURN #rtf
end'
set #counter = #counter + 1
exec #command
end
As i understand, the function is correct, the main problem to execute statement for function creation across multiple databases.
GO can't be used here, it's not sql, it's instruction to client to execute all statements in scope
Unfortunately, you can't create function not in current database, using [DatabaseName].[schema].[FuncName].
I can propose such technique to solve the problem, code just for example
declare #funccode nvarchar(4000);
set #funccode='CREATE FUNCTION [dbo].[fntest]
(
)
RETURNS int
AS
BEGIN
RETURN 1
END;'
declare #dbname nvarchar(100)='TestDatabase'
declare #statement nvarchar(max) ='use '+#dbname+';
exec (#func);'
exec sp_executesql #stmt = #statement,#params=N'#func nvarchar(4000)',#func=#funccode;
Th idea - to switch current database inside exec statement and call new exec statement, when current database is already set
Related
I am working on SQL Server (2005,2008 & 2012)
I wanna extract first five numbers from varchar column via using UDF
Input:
rrr123ddd4567ddd19828www2
123hhhsss124ss18762s
qq12349wsss12376ss
Output:
19828
18762
12349
My Trail is as following:
DECLARE
#myString VARCHAR(1000),
#temp VARCHAR(100),
#position INT,
#ExecuteInsert nvarchar (500),
#FirstChar bit
SET #myString = 'rrr123ddd4567ddd19828www2'
SET #position = 1
SET #FirstChar = 1
WHILE #position <= LEN(#myString)
BEGIN
IF (ISNUMERIC(SUBSTRING(#myString,#position,1))) = 1
BEGIN
SET #temp = isnull(#temp,'') + SUBSTRING(#myString,#position,1)
SET #FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (#FirstChar= 1)
BEGIN
SET #temp = isnull(#temp,'') + ','
SET #FirstChar = 0
END
END
SET #position = #position + 1
END
IF (RIGHT(#temp,1) <> ',')
BEGIN
SET #temp = #temp + ','
END
SELECT #temp = REPLACE(','+ #temp + ',',',,','')
SELECT #temp = Replace (#temp,',','''),(''')
Select #temp = '(''' + #temp + ''')'
Create table #temp
(
col1 varchar(100)
)
SET #ExecuteInsert = 'insert into #temp values ' + #temp
Execute sp_executesql #ExecuteInsert
select top 1 col1 from #temp
where LEN(col1) = 5
drop table #temp
-- Output >> 19828
The previous query is working well with string input , but I wanna using this code within UDF to could using it with columns.
if I used the previous query within UDF, the following error is raising:
Cannot access temporary tables from within a function.
EDIT
if I used Table variable , I get the next error:
Only functions and some extended stored procedures can be executed
from within a function.
any help will be greatly appreciated.
CREATE FUNCTION udfTest
(
-- Add the parameters for the function here
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE
#Result int,
#myString VARCHAR(1000),
#temp VARCHAR(100),
#position INT,
#ExecuteInsert nvarchar (500),
#FirstChar bit
SET #myString = 'rrr123ddd4567ddd19828www2'
SET #position = 1
SET #FirstChar = 1
WHILE #position <= LEN(#myString)
BEGIN
IF (ISNUMERIC(SUBSTRING(#myString,#position,1))) = 1
BEGIN
SET #temp = isnull(#temp,'') + SUBSTRING(#myString,#position,1)
SET #FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (#FirstChar= 1)
BEGIN
SET #temp = isnull(#temp,'') + ','
SET #FirstChar = 0
END
END
SET #position = #position + 1
END
IF (RIGHT(#temp,1) <> ',')
BEGIN
SET #temp = #temp + ','
END
SELECT #temp = REPLACE(','+ #temp + ',',',,','')
SELECT #temp = Replace (#temp,',','''),(''')
Select #temp = '(''' + #temp + ''')'
Declare #tempTable TABLE
(
col1 varchar(100)
)
insert into #tempTable SELECT #temp
select top 1 #Result=col1 from #tempTable
where LEN(col1) = 5
return #Result
END
GO
Here you are my answer of my question , hope helps others.
The objective is creating UDF function for using it with columns, not only fixed values.
The approach is using SplitString instead of sp_executesql
for splitting a comma separated string and loop it's values in table.
Demo:-
Create table DummyTable
( col1 varchar (100))
go
Insert into DummyTable values ('rrr123ddd4567ddd19828www2')
Insert into DummyTable values ('123hhhsss124ss18762s')
Insert into DummyTable values ('qq12349wsss12376ss')
go
/*
SplitString via Mudassar Khan
http://www.aspsnippets.com/Articles/Split-and-convert-Comma-Separated-Delimited-String-to-Table-in-SQL-Server.aspx
*/
Create FUNCTION SplitString
(
#Input NVARCHAR(MAX),
#Character CHAR(1)
)
RETURNS #Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE #StartIndex INT, #EndIndex INT
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output(Item)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1)
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
END
RETURN
END
GO
-------------------------------------
-------------------------------------
-------------------------------------
/*
My Own Function
*/
Create FUNCTION udfGetFirstFiveNumbers
(
#myString VARCHAR(1000)
)
RETURNS varchar(100)
AS
BEGIN
DECLARE
#temp VARCHAR(100),
#result Varchar (100),
#position INT,
#ExecuteInsert nvarchar (500),
#FirstChar bit
SET #position = 1
SET #FirstChar = 1
WHILE #position <= LEN(#myString)
BEGIN
IF (ISNUMERIC(SUBSTRING(#myString,#position,1))) = 1
BEGIN
SET #temp = isnull(#temp,'') + SUBSTRING(#myString,#position,1)
SET #FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (#FirstChar= 1)
BEGIN
SET #temp = isnull(#temp,'') + ','
SET #FirstChar = 0
END
END
SET #position = #position + 1
END
IF (RIGHT(#temp,1) <> ',')
BEGIN
SET #temp = #temp + ','
END
SELECT #temp = REPLACE(','+ #temp + ',',',,','')
SELECT #result = Item
FROM dbo.SplitString(#temp, ',')
where len(Item) = 5
return #result
END
GO
-- Test
select col1, dbo.udfGetFirstFiveNumbers(col1) as result
from DummyTable
Result:-
I am trying to create a dynamic query in SQL Server.
Input: #value= abc,def,en,
Output: MAX(abc) as abc, MAX(def) as def, MAX(en) as en
My efforts so far took me no where.
With CONVERT() and REPLACE() I achieved a bit but finding it difficult. Need help!
Try this:
declare #value varchar(50) = 'abc,def,en'
declare #result varchar(100) = ''
select #result = replace(#value,'abc', 'MAX(''abc'') as abc')
select #result = replace(#result,'def', 'MAX(''def'') as def')
select #result = replace(#result,'en', 'MAX(''en'') as en')
select #result
You can also do the replacements in one line by nesting the expressions.
EDIT: If you have variable values in #value, you can take the below approach:
Use a splitter function to get the individual values in the string as a list. You can take a look at this article for implementations.
Insert this list to a temp table.
Update the temp table as shown above.
Concatenate the values into a single string using STUFF like so:
select stuff((select ',' + val from #temp for xml path('')),1,1,'')
Try this:
DECLARE #Value VARCHAR(200) = 'abc,def,en'
DECLARE #Template VARCHAR(100) = 'MAX(''##'') as ##'
DECLARE #Result VARCHAR(1000) = ''
DECLARE #Data VARCHAR(100) = ''
WHILE LEN(#Value) > 0
BEGIN
SET #Data = REPLACE(LEFT(#Value, ISNULL(NULLIF(CHARINDEX(',', #Value),0), LEN(#Value))),',','')
SET #Result = #Result + REPLACE(#Template, '##', #Data)
IF CHARINDEX(',', #Value) > 0
BEGIN
SET #Result = #Result + ','
SET #Value = REPLACE(#Value,#Data + ',','')
END
ELSE
SET #Value = REPLACE(#Value,#Data,'')
END
SELECT #Result
Have a look at SQL User Defined Function to Parse a Delimited String
So you can do like
Declare #Value varchar(200) = 'abc,def,en'
Declare #Item varchar(20) = null
declare #Str varchar(1000)=''
WHILE LEN(#Value) > 0
BEGIN
IF PATINDEX('%,%',#Value) > 0
BEGIN
SET #Item = SUBSTRING(#Value, 0, PATINDEX('%,%',#Value))
-- SELECT #Item
IF(LEN(#Str)>0)
SET #Str = #Str + ', SELECT MAX('+#Item+') as ' +#Item
ELSE
SET#Str = #Str + ' SELECT MAX('+#Item+') as ' +#Item
SET #Value = SUBSTRING(#Value, LEN(#Item + ',') + 1, LEN(#Value))
END
ELSE
BEGIN
SET #Item = #Value
SET #Value = NULL
SET #Str = #Str + 'SELECT MAX('+#Item+') as ' + #Item
END
END
select #Str
See the fiddle sample here
I have a scalar-valued [return type nvarchar] function that returns a dynamic Query String.
Let my Function is like following …
CREATE FUNCTION ABC
(
)
RETURNS nvarchar(MAX)
AS
BEGIN
return 'Select * from Table1'
END
I want to Execute it like following …
Select * from dbo.ABC()
Or
Select * from EXEC(dbo.ABC())
Is That possible in SQL Server 2012?
I have to do it without using openquery.
-- My Actual Function --
ALTER FUNCTION [dbo].[RowToColumn]
(
-- Add the parameters for the function here
)
RETURNS nvarchar(MAX)
AS
BEGIN
DECLARE #PunchList nvarchar(MAX)
DECLARE #PunchListTOP nvarchar(MAX)
DECLARE #SQL nvarchar(MAX)
DECLARE #Flag INT
SET #PunchList = ''
SET #PunchListTOP = ''
DECLARE #I INT
SET #Flag = (select MAX(X) as MMAX from (select Employee_ID,Date_Of_Working, count(Date_Of_Working) as X from DataInOneRowStep3 group by Date_Of_Working ,Employee_ID ) A)
Set #I =1
WHILE (#I<= #Flag)
BEGIN
if (#PunchList = '' )
BEGIN
Set #PunchList = 'Punch_' + CONVERT(varchar, #I)
Set #PunchListTOP = ' MAX(Punch_' + CONVERT(varchar, #I) +') Punch_' + CONVERT(varchar, #I)
END
else
BEGIN
Set #PunchList = #PunchList + ',' + 'Punch_' + CONVERT(varchar, #I)
Set #PunchListTOP =#PunchListTOP +','+ ' MAX(Punch_' + CONVERT(varchar, #I) +') Punch_' + CONVERT(varchar, #I)
END
SET #I = #I + 1
END
SET #SQL ='SELECT Employee_Id,Date_OF_Working,Shift_Id,'+#PunchListTOP+' FROM (
SELECT * from DataInOneRowStep4
) as s
PIVOT
(
MAX(EntryTime)
FOR Punch IN ('+#PunchList+')
)AS piv group by Employee_Id,Date_OF_Working,Shift_Id'
RETURN #SQL
END
I googled a lot to wrap string with minimum defined length, but I am unable to get any solution.
I created my own function that can wrap text by given number of characters per line.
This post may help to others looking for same.
Function 1
Create FUNCTION [dbo].[fn_BraekTextInLines]
(
-- Add the parameters for the function here
#InString varchar(max),
#LineLength int
)
RETURNS nvarchar(max)
AS
BEGIN
if #LineLength <=0 or #LineLength> LEN(#InString)
return #InString
declare #tmp varchar(max)
declare #result varchar(max)
DECLARE #word varchar (max);
declare #addedInResult bit
DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT s FROM SplitMax(#InString,'');
OPEN c;
FETCH NEXT FROM c INTO #word;
--set #tmp =#word
WHILE ##FETCH_STATUS = 0
BEGIN
if LEN(#tmp + ' ' + #word) < #LineLength
begin
set #tmp = #tmp + ' ' + #word
set #addedInResult = 0
end
else
begin
set #result = isnull(#result, ' ') + CHAR(13) + RTRIM(LTRIM( #tmp))
set #tmp = #word
set #addedInResult = 1
end
FETCH NEXT FROM c INTO #word;
if ##FETCH_STATUS <> 0
begin
set #result = isnull(#result, ' ') + CHAR(13) + RTRIM(LTRIM( #tmp))
set #addedInResult = 1
end
END
CLOSE c;
DEALLOCATE c;
if #addedInResult=0
begin
set #result = isnull(#result, ' ') + CHAR(13) + RTRIM(LTRIM( #tmp))
end
return #result
END
Function 2
Create FUNCTION [dbo].[fn_WrapString]
(
-- Add the parameters for the function here
#InString varchar(max),
#LineLength int
)
RETURNS nvarchar(max)
AS
BEGIN
declare #result varchar(max)
declare #tmp varchar(max)
DECLARE #Line varchar (max);
DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT s FROM SplitMax(#InString,CHAR(13));
OPEN c;
FETCH NEXT FROM c INTO #Line;
WHILE ##FETCH_STATUS = 0
BEGIN
set #tmp = dbo.fn_BraekTextInLines(#Line,#LineLength)
set #result = isnull(#result,' ') + #tmp
FETCH NEXT FROM c INTO #Line;
END
CLOSE c;
DEALLOCATE c;
return Rtrim(Ltrim(#result))
END
Function 3
ALTER FUNCTION [dbo].[SplitMax](#String VARCHAR(max), #Delimiter CHAR(1))
RETURNS #temptable TABLE (s VARCHAR(max))
AS
BEGIN
DECLARE #idx INT
DECLARE #slice VARCHAR(max)
SELECT #idx = 1
IF len(#String)<1 OR #String IS NULL RETURN
while #idx!= 0
BEGIN
SET #idx = charindex(#Delimiter,#String)
IF #idx!=0
SET #slice = LEFT(#String,#idx - 1)
ELSE
SET #slice = #String
IF(len(#slice)>0)
INSERT INTO #temptable(s) VALUES(#slice)
SET #String = RIGHT(#String,len(#String) - #idx)
IF len(#String) = 0 break
END
RETURN
END
Calling Function fn_WrapString to wrap the text
declare #name varchar(max)
set #name = 'Ine was King of Wessex from 688 to 726. He was'+ CHAR(13) +'unable to retain the territorial gains of his predecessor, Cædwalla, who had brought much of southern England under his'
print dbo.fn_WrapString(#name,60)
Output :
Ine was King of Wessex from 688 to 726. He was
unable to retain the territorial gains of his predecessor,
Cædwalla, who had brought much of southern England under
his
I also created a short version for warping the text in T-Sql
CREATE FUNCTION [dbo].[WrapText]
(
#List NVARCHAR(MAX),
#length INT
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #result AS NVARCHAR(MAX);
SELECT #result = CASE
WHEN #result IS NULL THEN
SUBSTRING(#List, number.Number - #length + 1, #length)
ELSE
#result + CHAR(13) + CHAR(10) + SUBSTRING(#List, number.Number - #length + 1, #length)
END
FROM
(
SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects
) number
WHERE number.Number <= LEN(#List) + #length - 1
AND number.Number % #length = 0;
RETURN #result;
END;
Calling Function:
SELECT dbo.WrapText('abcdefghijklmnopqrstuvwxyz',5)
If you are coping the result from grid, it will not past with line breaks as explained here
https://stackoverflow.com/a/59189881/1606054
I am trying to create multiple triggers with only uploading one script into an Oracle DB / APEX workspace, and running it once.
Here is a brief script compared to the one im trying to use:
create or replace trigger "BI_TEC_ROLES"
before insert on "TEC_ROLES"
for each row
begin
if :NEW."ROLE_ID" is null then
select "TEC_ROLES_SEQ".nextval into :NEW."ROLE_ID" from dual;
end if;
end;
create or replace trigger "BI_TEC_STATUSES"
before insert on "TEC_STATUSES"
for each row
begin
if :NEW."STATUS_ID" is null then
select "TEC_STATUSES_SEQ".nextval into :NEW."STATUS_ID" from dual;
end if;
end;
create or replace trigger "BI_TEC_SUBS"
before insert on "TEC_SUBS"
for each row
begin
if :NEW."SUB_ID" is null then
select "TEC_SUBS_SEQ".nextval into :NEW."SUB_ID" from dual;
end if;
end;
I have tried putting GO in between each individual block, but still only creates the first trigger then gives me an error for the second saying:
Error(7,1): PLS-00103: Encountered the symbol "CREATE"
I am hoping that it is possible to do this. Thank you very much for your time and interest =)
Add a forward slash on a new line after each trigger to execute the command in the buffer:
create trigger...
...
end;
/
Put a slash '/' as the first character on a blank line between each trigger statement. This is the SQL*PLUS equivalent of 'go'.
Yes we can execute multiple procedure/trigger/function in single script using the FORWARD SLASH / inside the sql file.
Like below:
create or replace trigger "BI_TEC_ROLES"
before insert on "TEC_ROLES"
for each row
begin
if :NEW."ROLE_ID" is null then
select "TEC_ROLES_SEQ".nextval into :NEW."ROLE_ID" from dual;
end if;
end;
/
create or replace trigger "BI_TEC_STATUSES"
before insert on "TEC_STATUSES"
for each row
begin
if :NEW."STATUS_ID" is null then
select "TEC_STATUSES_SEQ".nextval into :NEW."STATUS_ID" from dual;
end if;
end;
/
create or replace trigger "BI_TEC_SUBS"
before insert on "TEC_SUBS"
for each row
begin
if :NEW."SUB_ID" is null then
select "TEC_SUBS_SEQ".nextval into :NEW."SUB_ID" from dual;
end if;
end;
/
Then oracle will consider it as new statement/block.
Place a forward slash
/
between the two statements on a separate line.
Oracle will then accept it as a new statement
--Parameter:
-- #InclDrop bit
-- Possible values
-- 0 - Script to drop the triggers is not generated.
-- 1 - Script to drip the triggers is generated.
SET ansi_nulls ON
go
SET quoted_identifier ON
go
ALTER PROCEDURE [dbo].[Createscriptofalltriggers]
#InclDrop BIT =1
AS
DECLARE #SQL VARCHAR(8000),
#Text NVARCHAR(4000),
#BlankSpaceAdded INT,
#BasePos INT,
#CurrentPos INT,
#TextLength INT,
#LineId INT,
#MaxID INT,
#AddOnLen INT,
#LFCR INT,
#DefinedLength INT,
#SyscomText NVARCHAR(4000),
#Line NVARCHAR(1000),
#UserName SYSNAME,
#ObjID INT,
#OldTrigID INT
SET nocount ON
SET #DefinedLength = 1000
SET #BlankSpaceAdded = 0
IF #InclDrop <> 0
SET #InclDrop =1
-- This Part Validated the Input parameters
DECLARE #Triggers TABLE
(
username SYSNAME NOT NULL,
trigname SYSNAME NOT NULL,
objid INT NOT NULL
)
DECLARE #TrigText TABLE
(
objid INT NOT NULL,
lineid INT NOT NULL,
linetext NVARCHAR(1000) NULL
)
INSERT INTO #Triggers
(username,
trigname,
objid)
SELECT DISTINCT A.NAME,
B.NAME,
B.id
FROM dbo.sysusers A,
dbo.sysobjects B,
dbo.syscomments C
WHERE A.uid = B.uid
AND B.type = 'Tr'
AND B.id = C.id
AND C.encrypted = 0
IF EXISTS(SELECT C.*
FROM syscomments C,
sysobjects O
WHERE O.id = C.id
AND O.type = 'Tr'
AND C.encrypted = 1)
BEGIN
PRINT '/*'
PRINT 'The following encrypted triggers were found'
PRINT 'The procedure could not write the script for it'
SELECT DISTINCT A.NAME,
B.NAME,
B.id
FROM dbo.sysusers A,
dbo.sysobjects B,
dbo.syscomments C
WHERE A.uid = B.uid
AND B.type = 'Tr'
AND B.id = C.id
AND C.encrypted = 1
PRINT '*/'
END
DECLARE ms_crs_syscom CURSOR local forward_only FOR
SELECT T.objid,
C.text
FROM #Triggers T,
dbo.syscomments C
WHERE T.objid = C.id
ORDER BY T.objid,
C.colid
FOR READ only
SELECT #LFCR = 2
SELECT #LineId = 1
OPEN ms_crs_syscom
SET #OldTrigID = -1
FETCH next FROM ms_crs_syscom INTO #ObjID, #SyscomText
WHILE ##fetch_status = 0
BEGIN
SELECT #BasePos = 1
SELECT #CurrentPos = 1
SELECT #TextLength = Len(#SyscomText)
IF #ObjID <> #OldTrigID
BEGIN
SET #LineID = 1
SET #OldTrigID = #ObjID
END
WHILE #CurrentPos != 0
BEGIN
--Looking for end of line followed by carriage return
SELECT #CurrentPos = Charindex(Char(13) + Char(10), #SyscomText,
#BasePos)
--If carriage return found
IF #CurrentPos != 0
BEGIN
WHILE ( Isnull(Len(#Line), 0) + #BlankSpaceAdded
+ #CurrentPos - #BasePos + #LFCR ) >
#DefinedLength
BEGIN
SELECT #AddOnLen = #DefinedLength - (
Isnull(Len(#Line),
0
) +
#BlankSpaceAdded )
INSERT #TrigText
VALUES ( #ObjID,
#LineId,
Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText, #BasePos,
#AddOnLen),
N''))
SELECT #Line = NULL,
#LineId = #LineId + 1,
#BasePos = #BasePos + #AddOnLen,
#BlankSpaceAdded = 0
END
SELECT #Line = Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText, #BasePos,
#CurrentPos
-#BasePos +
#LFCR),
N'')
SELECT #BasePos = #CurrentPos + 2
INSERT #TrigText
VALUES( #ObjID,
#LineId,
#Line )
SELECT #LineId = #LineId + 1
SELECT #Line = NULL
END
ELSE
--else carriage return not found
BEGIN
IF #BasePos <= #TextLength
BEGIN
/*If new value for #Lines length will be > then the
**defined length
*/
WHILE ( Isnull(Len(#Line), 0) + #BlankSpaceAdded
+ #TextLength - #BasePos + 1 ) >
#DefinedLength
BEGIN
SELECT #AddOnLen = #DefinedLength - (
Isnull(Len(#Line),
0
) +
#BlankSpaceAdded )
INSERT #TrigText
VALUES ( #ObjID,
#LineId,
Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText,
#BasePos,
#AddOnLen),
N''))
SELECT #Line = NULL,
#LineId = #LineId + 1,
#BasePos = #BasePos + #AddOnLen,
#BlankSpaceAdded = 0
END
SELECT #Line = Isnull(#Line, N'')
+ Isnull(Substring(#SyscomText,
#BasePos,
#TextLength
-#BasePos+1
), N'')
IF Len(#Line) < #DefinedLength
AND Charindex(' ', #SyscomText, #TextLength + 1)
> 0
BEGIN
SELECT #Line = #Line + ' ',
#BlankSpaceAdded = 1
END
END
END
END
FETCH next FROM ms_crs_syscom INTO #ObjID, #SyscomText
END
IF #Line IS NOT NULL
INSERT #TrigText
VALUES( #ObjID,
#LineId,
#Line )
CLOSE ms_crs_syscom
PRINT '-- You should run this result under dbo if your triggers belong to multiple users'
PRINT ''
IF #InclDrop = 1
BEGIN
PRINT '-- Dropping the Triggers'
PRINT ''
SELECT 'If exists(Select * from sysObjects where id =Object_ID(''['
+ username + '].[' + trigname
+ ']'') and ObjectProperty(Object_ID(''['
+ username + '].[' + trigname + ']''), ''ISTRIGGER'')=1) Drop Trigger ['
+ username + '].[' + trigname + '] ' + Char(13)
+ Char(10) + 'GO' + Char(13) + Char(10) + Char(13)
+ Char(10)
FROM #Triggers
END
PRINT '----------------------------------------------'
PRINT '-- Creation of Triggers'
PRINT ''
PRINT ''
DECLARE ms_users CURSOR local forward_only FOR
SELECT T.username,
T.objid,
Max(D.lineid)
FROM #Triggers T,
#TrigText D
WHERE T.objid = D.objid
GROUP BY T.username,
T.objid
FOR READ only
OPEN ms_users
FETCH next FROM ms_users INTO #UserName, #ObjID, #MaxID
WHILE ##fetch_status = 0
BEGIN
PRINT 'SetUser N''' + #UserName + '''' + Char(13)
+ Char(10)
SELECT '-- Text of the Trigger'= CASE lineid
WHEN 1 THEN 'GO' + Char(13) + Char(
10)
+
linetext
WHEN #MaxID THEN linetext + 'GO'
ELSE linetext
END
FROM #TrigText
WHERE objid = #ObjID
ORDER BY lineid
PRINT 'Setuser'
FETCH next FROM ms_users INTO #UserName, #ObjID, #MaxID
END
CLOSE ms_users
PRINT 'GO'
PRINT '------End ------'
DEALLOCATE ms_crs_syscom
DEALLOCATE ms_users
SET nocount ON
DECLARE #return_value INT
How to execute it:
EXEC #return_value = [dbo].[Createscriptofalltriggers]
#InclDrop = 1
SELECT 'Return Value' = #return_value
go