How to split and replace with stored procedure? - sql

I want to replace all e_Mail column where in #tablename with my users table (my main table).
For example:
#tablename
[name] [eMail] // columns
------------------------------------------------------
name surname blahblah#gmail.com
My users table
[name] [eMail]
----------------------------------------
name surname blahblah#hotmail.com
I want to update this row's eMail column as 'blahblah#hotmail.com' in #tablename.
What will procedure do?
1- Get first value of eMail column from #tablename
2- Split value (split char: #) and get first value (for example, if value blahblah#gmail.com, get gmail.com)
3- Search first value in users table
4- When the find value in users table, (Code must find blahblah#hotmail.com) Update eMail as blahblah#hotmail.com in #tablename
5- Get second value of eMail column from #tablename
.
.
.
So, I write a stored procedure. But this procedure is not working. Where is the problem?
Create Proc update_eMail
(#tablename nvarchar(50),
#columnname nvarchar(50))
AS
Begin
Declare #get_oldeMail nvarchar(100)
Declare #get_eMail nvarchar(100)
Declare #get_SplitValue nvarchar(100)
Declare #get_oldSplitValue nvarchar(100)
Declare #rowNumber int
Declare #users_rowNumber int
Declare #i int
Declare #j int
Declare #q_getRowNumber NVARCHAR(MAX)
Declare #q_getoldeMail NVARCHAR(MAX)
Declare #q_UpdateQuery NVARCHAR(MAX)
SET #q_getRowNumber = N'SELECT Count(ID)
FROM ' + QUOTENAME(#tablename)
EXECUTE #rowNumber = sp_executesql #q_getRowNumber
/*Set #rowNumber = (Select Count(ID) from #tablename)*/
Set #users_rowNumber = (Select Count(ID) from tblusers)
Set #i = 1
Set #j = 1
While(#i <= #rowNumber)
BEGIN
Set #q_getoldeMail = '(SELECT Lower(#columnname) FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS rownumber
,ID
,[Name]
,[Description]
,[Status]
,[AssignedTo]
,[AssignedToMail]
,[CC]
FROM' + #tablename + '
) AS ar
WHERE rownumber = #i)'
EXECUTE #get_oldeMail = sp_executesql #q_getoldeMail
Set #get_oldeMail = REPLACE(#get_oldeMail,'ı','i')
WHILE LEN(#get_oldeMail) > 0
BEGIN
IF CHARINDEX('#',#get_oldeMail) > 0
SET #get_oldSplitValue = SUBSTRING(#get_oldeMail,0,CHARINDEX('#',#get_oldeMail))
ELSE
BEGIN
SET #get_oldSplitValue = #get_oldeMail
SET #get_oldeMail = ''
END
SET #get_oldeMail = REPLACE(#get_oldeMail,#get_oldSplitValue + '#' , '')
END
While(#j <= #users_rowNumber)
BEGIN
Set #get_eMail = (SELECT Replace(Lower(eMail),'ı','i') FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY ID) AS rownumber
,eMail
FROM tblusers) AS ar
WHERE rownumber = #j)
WHILE LEN(#get_eMail) > 0
BEGIN
IF CHARINDEX('#',#get_eMail) > 0
SET #get_SplitValue = SUBSTRING(#get_eMail,0,CHARINDEX('#',#get_eMail))
ELSE
BEGIN
SET #get_SplitValue = #get_eMail
SET #get_eMail = ''
END
SET #get_eMail = REPLACE(#get_eMail,#get_SplitValue + '#' , '')
END
if(#get_splitValue = #get_oldSplitValue)
begin
Set #q_UpdateQuery = 'Update ar Set ' + #columnname + ' = ' + #get_email + ' Where rownumber = ' +#i
EXECUTE sp_executesql #q_UpdateQuery
break
end
SET #j = #j+1
END
SET #i = #i+1
END
End
Thanks in advance.

Related

Search a string in whole mysql database

I wrote this query for searching a string in whole database . Earlier it was working properly now it doesn't fetch full result at all . I don't get what is wrong with this query . Please help
QUERY
/*
- Search through tables to find specific text
- Written by Luis Chiriff (with help from SQL Server Central)
- luis.chiriff#gmail.com # 24/11/2008 # 11:54
*/
-- Variable Declaration
Declare #StringToFind VARCHAR(200), #Schema sysname, #Table sysname, #FullTable int, #NewMinID
int, #NewMaxID int,
#SQLCommand VARCHAR(8000), #BaseSQLCommand varchar(8000), #Where VARCHAR(8000), #CountCheck
varchar(8000) , #FieldTypes varchar(8000),
#cursor VARCHAR(8000), #columnName sysname, #SCn int, #SCm int
Declare #TableList table (Id int identity(1,1) not null, tablename varchar(250))
Declare #SQLCmds table (id int identity(1,1) not null, sqlcmd varchar(8000))
Declare #DataFoundInTables table (id int identity(1,1) not null, sqlcmd varchar(8000))
-- Settings
SET #StringToFind = 'abcdef'
SET NOCOUNT ON
SET #StringToFind = '%'+#StringToFind+'%'
-- Gathering Info
if ((select count(*) from sysobjects where name = 'tempcount') > 0)
drop table tempcount
create table tempcount (rowsfound int)
insert into tempcount select 0
-- This section here is to accomodate the user defined datatypes, if they have
-- a SQL Collation then they are assumed to have text in them.
SET #FieldTypes = ''
select #FieldTypes = #FieldTypes + '''' + rtrim(ltrim(name))+''',' from systypes where collation
is not null or xtype = 36
select #FieldTypes = left(#FieldTypes,(len(#FieldTypes)-1))
insert into #TableList (tablename)
select name from sysobjects
where xtype = 'U' and name not like 'dtproperties'
order by name
-- Start Processing Table List
select #NewMinID = min(id), #NewMaxID = max(id) from #TableList
while(#NewMinID <= #NewMaxID)
Begin
SELECT #Table = tablename, #Schema='dbo', #Where = '' from #TableList where id = #NewMinID
SET #SQLCommand = 'SELECT * FROM ' + #Table + ' WHERE'
-- removed ' + #Schema + '.
SET #cursor = 'DECLARE col_cursor CURSOR FOR SELECT COLUMN_NAME
FROM [' + DB_NAME() + '].INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = ''' + #Schema + '''
AND TABLE_NAME = ''' + #Table + '''
AND DATA_TYPE IN ('+#FieldTypes+')'
--Original Check, however the above implements user defined data types --AND DATA_TYPE IN
(''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')'
EXEC (#cursor)
SET #FullTable = 0
DELETE FROM #SQLCmds
OPEN col_cursor
FETCH NEXT FROM col_cursor INTO #columnName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Where = #Where + ' [' + #columnName + '] LIKE ''' + #StringToFind + ''''
SET #Where = #Where + ' OR'
--PRINT #Table + '|'+ cast(len(isnull(#Where,''))+len(isnull(#SQLCommand,'')) as varchar(10))+'|'+#Where
if (len(isnull(#Where,''))+len(isnull(#SQLCommand,'')) > 3600)
Begin
SELECT #Where = substring(#Where,1,len(#Where)-3)
insert into #SQLCmds (sqlcmd) select #Where
SET #Where = ''
End
FETCH NEXT FROM col_cursor INTO #columnName
END
CLOSE col_cursor
DEALLOCATE col_cursor
if (#Where <> '')
Begin
SELECT #Where = substring(#Where,1,len(#Where)-3)
insert into #SQLCmds (sqlcmd)
select #Where --select #Table,count(*) from #SQLCmds
End
SET #BaseSQLCommand = #SQLCommand
select #SCn = min(id), #SCm = max(id) from #SQLCmds
while(#SCn <= #SCm)
Begin
select #Where = sqlcmd from #SQLCmds where ID = #SCn
if (#Where <> '')
Begin
SET #SQLCommand = #BaseSQLCommand + #Where
SELECT #CountCheck = 'update tempcount set rowsfound = (select count(*) '+ substring(#SQLCommand,10,len(#SQLCommand)) + ')'
EXEC (#CountCheck)
if ((select rowsfound from tempcount) > 0)
Begin
PRINT '--- ['+cast(#NewMinID as varchar(15))+'/'+cast(#NewMaxID as varchar(15))+'] '+#Table + ' ----------------------------------[FOUND!]'
--PRINT '--- [FOUND USING:] ' +#SQLCommand
insert into #DataFoundInTables (sqlcmd) select #SQLCommand
EXEC (#SQLCommand)
update tempcount set rowsfound = 0
End
else
Begin
PRINT '--- ['+cast(#NewMinID as varchar(15))+'/'+cast(#NewMaxID as varchar(15))+'] '+#Table
End
End
SET #SCn = #SCn + 1
End
set #NewMinID = #NewMinID + 1
end
if ((select count(*) from sysobjects where name = 'tempcount') > 0)
drop table tempcount
/*
This will now return all the sql commands you need to use
*/
select #NewMinID = min(id), #NewMaxID = max(id) from #DataFoundInTables
if (#NewMaxID > 0)
Begin
PRINT ' '
PRINT ' '
PRINT '-----------------------------------------'
PRINT '----------- TABLES WITH DATA ------------'
PRINT '-----------------------------------------'
PRINT ' '
PRINT 'We found ' + cast(#NewMaxID as varchar(10)) + ' table(s) with the string '+#StringToFind
PRINT ' '
while(#NewMinID <= #NewMaxID)
Begin
select #SQLCommand = sqlcmd from #DataFoundInTables where ID = #NewMinID
PRINT #SQLCommand
SET #NewMinID = #NewMinID + 1
End
PRINT ' '
PRINT '-----------------------------------------'
End
This query was working fine one month ago but now it doesn't fetch the results . Can anyone tell me what is wrong in this query .

How can i optimize the Trigger

I have checked a lot of Question asked Previously but was not able to get how do optimize this trigger
ALTER trigger [dbo].[Expample]
on [dbo].[AdminUsers]
for update
as begin
declare #Id int
declare #new_val nvarchar(max)
declare #old_val nvarchar(max)
Declare #AuditString nvarchar(max)
Select *
into #TempTable
from inserted
While(Exists(Select Id from #TempTable))
Begin
Set #AuditString = ''
Select Top 1 #Id = Id,#new_val = Fname
from #TempTable
Select #old_val = Fname
from deleted where Id = #Id
Set #AuditString = 'Id = ' + Cast(#Id as nvarchar(4)) + ' changed'
if(#old_val <> #new_val)
Set #AuditString = #AuditString + ' NAME from ' + #old_val + ' to ' + #new_val
insert into [dbo].[tbl_audit] (Id,Auditdata) values(#Id,#AuditString)
-- Delete the row from temp table, so we can move to the next row
Delete from #TempTable where Id = #Id
end
end
How I have changed this code to
ALTER trigger [dbo].[Expample]
on [dbo].[AdminUsers]
for update
as begin
declare #Id int
declare #new_val nvarchar(max)
declare #old_val nvarchar(max)
Declare #AuditString nvarchar(max)
Begin
Set #AuditString = ''
Select Top 1 #Id=inserted.Id,#new_val =inserted.Fname,#old_val = deleted.Fname from inserted join deleted on inserted.Id=deleted.Id
-- Select Top 1 #Id = Id,#new_val = Fname
-- from #TempTable
--Select #old_val = Fname
--from deleted where Id = #Id
Set #AuditString = 'Id = ' + Cast(#Id as nvarchar(4)) + ' changed'
if(#old_val <> #new_val)
Set #AuditString = #AuditString + ' NAME from ' + #old_val + ' to ' + #new_val
insert into [dbo].[tbl_audit] (Id,Auditdata) values(#Id,#AuditString)
-- Delete the row from temp table, so we can move to the next row
end
end
Thanks for Help
I have not been able to test it, but it appears this is what you are trying to accomplish:
ALTER trigger [dbo].[Expample]
on [dbo].[AdminUsers]
for update
as begin
insert into [dbo].[tbl_audit] (Id, Auditdata)
select t1.Id, 'Id = ' + Cast(t1.Id as nvarchar(4)) + ' changed NAME from ' + t2.Fname + ' to ' + t1.Fname
from inserted t1
join deleted t2 on t2.Id = t1.Id and t2.Fname != t1.Fname

Generate script with INSERT SELECT statements from T-SQL

I have two databases in SQL Server 2014 Express, since a few days ago I am unifying both databases in such a way that there is only one left.
When I have this new database I must pass it to Azure (I don't have any experience using this technology), however, I am doing tests on my local server, so far I have created the whole scheme but I must fill out all the tables to perform tests with my application.
There are 313 tables of which many have more than 200,000 records, my question is, what is the best way to populate the database?
Because at this moment I want to test my local machine, I could fill in the tables through Tasks> Generate Script> Advanced Options (Include only data) but this information will change the day when the migration to Azure is done, therefore I must Do the same process.
So, is it possible to create an INSERT SELECT script so that it does not include records one by one and is as dynamic as possible? For example, you would have to generate an INSERT INTO similar to this:
SET IDENTITY_INSERT [SchemaX].[TableA] ON ;
INSERT INTO [SchemaX].[TableA]
(
[id]
,[fieldA]
,[fieldB]
,[fieldC])
SELECT
[id]
,[fieldA]
,[fieldB]
,[fieldC]
FROM [server].[dbname].[SchemaX].[TableA]
SET IDENTITY_INSERT [SchemaX].[TableA] OFF ;
Some tables have IDENTITY enabled so you would have to recognize which tables are like this and use SET IDENTITY_INSERT when inserting. This way you would have to link the production server and insert the information into the local server.
If there are suggestions or recommendations about another way you are welcome
Has been answered before ...
/****** Object: StoredProcedure [dbo].[procUtils_GenerateInsertProc] Script Date: 03/20/2010 13:06:13 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[procUtils_GenerateInsertProc]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[procUtils_GenerateInsertProc]
GO
/****** Object: StoredProcedure [dbo].[procUtils_GenerateInsertProc] Script Date: 03/20/2010 13:06:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--exec procUtils_GenerateInsertProc 'Whatever'
--exec sp_HelpText procUtils_GenerateInsertProc
CREATE PROCEDURE [dbo].[procUtils_GenerateInsertProc]
#TableName [varchar](50)
WITH EXECUTE AS CALLER
AS
BEGIN -- proc start
SET NOCOUNT ON;
BEGIN TRY --begin try
--FIRST SEARCH THE TABLE WHICH HAD A "Feature" in its name
--SELECT NAME FROM SYS.TABLES WHERE NAME LIKE '%Feature%'
--SELECT column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Feature' --SELECT * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='Task'
--Decalre a variable to remember the position of the current delimiter
DECLARE #ProcName varchar(1000)
set #ProcName = '[dbo].[procGen_' + #TableName + '_Insert]'
DECLARE #CurrentDelimiterPositionVar INT
DECLARE #PkColumnName varchar(200)
--Decalre a variable to remember the number of rows in the table
DECLARE #Count INT
DECLARE #ColumnName varchar(300);
DECLARE #DataType varchar(50)
DECLARE #IsNullable bit
DECLARE #MaxLength INT
DECLARE #IsComputed BIT
set #IsComputed = 0
DECLARE #IsPrimaryKey BIT
set #IsPrimaryKey = 0
DECLARE #CODESTR VARCHAR(max)
--PRINT DROP PROCEDURE
set #CODESTR = ' '
--Declare the Table variable
DECLARE #ColumnNames TABLE
(
Number INT IDENTITY(1,1), --Auto incrementing Identity column
TableName varchar(300) , --the name of the table
ColumnName VARCHAR(300) , --The string value ,
DataType varchar(50) , --the datatype
IsNullable bit , --should we add =null in front
MaxLength INT , --VARCHAR(LENGHTi)
IsComputed bit , --whether or not this table is computed
IsPrimaryKey bit --whether or not this table is computed
)
--Populate the TABLE variable using some logic
-- SELECT * from INFORMATION_SCHEMA.COLUMNS
INSERT INTO #ColumnNames
(
TableName ,
ColumnName ,
DataType ,
IsNullable ,
MaxLength ,
IsComputed ,
IsPrimaryKey )
SELECT
TableName ,
ColumnName ,
DataType ,
IsNullable ,
MaxLength ,
IsComputed ,
IsPrimaryKey
from viewMeta_TableColumns
--debug where TableName = 'Whatever'
where TableName = #TableName
--SELECT column_name , Data_type , IsNullable , MaxLength
--from INFORMATION_SCHEMA.COLUMNS
--where TABLE_NAME=#TableName
--Initialize the looper variable
SET #CurrentDelimiterPositionVar = 1
--Determine the number of rows in the Table
SELECT #Count=max(Number) from #ColumnNames
--A variable to hold the currently selected value from the table
set #CODESTR = #CODESTR + 'IF OBJECT_ID(''' + #ProcName + ''') IS NOT NULL
BEGIN
DROP PROC ' + #ProcName + '
END
GO'
set #CODESTR = #CODESTR + '
/****** Object: StoredProcedure ' + #ProcName + '*/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE ' + #ProcName + '
#CurUserSessionId [int] ,
#CurPageTypeId [int] ,
#MsgOut [varchar](200) OUTPUT ,
#DebugMsgOut [varchar](200) OUTPUT,
#Ret [int] OUTPUT ,' + CHAR(13)
--#COLUMN_NAME [DATA_TYPE] (MAX_LENGTH) =NULL ,
WHILE #CurrentDelimiterPositionVar <= #Count --1st loop
BEGIN
--Load current value from the Table
SELECT #ColumnName = ColumnName FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #DataType = DataType FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #MaxLength = MaxLength FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
set #IsNullable = ( select IsNullable FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
if ( #DataType = 'timestamp' or #IsComputed = 1)
begin
set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
continue
end
set #CODESTR = #CODESTR + '#' + #ColumnName + ' ['+ #DataType + '] '
--ADD THE (200)
IF #MaxLength IS NOT NULL
BEGIN --IF #MaxLength IS NOT NULL
--xml
if #DataType <> 'xml' and #DataType <> 'sql_variant' and
#DataType <> 'text' and #DataType <> 'ntext' and #DataType <> 'image' and
#DataType <> 'hierarchyid' and #DataType <> 'bit' and #DataType <> 'varbinary' and
#DataType <> 'int' and #DataType <> 'uniqueidentifier' and #DataType <> 'tinyint' and
#DataType <> 'timestamp' and #DataType <> 'uniqueidentifier' and #DataType <> 'smallint' and
#DataType <> 'bigint' and #DataType <> 'smallmoney' and #DataType <> 'money' and
#DataType <> 'real' and #DataType <> 'smalldatetime' and #DataType <> 'datetime'
begin --those with()
if #MaxLength <> -1
SET #CODESTR = #CODESTR + '(' + CONVERT(VARCHAR , #MaxLength ) + ')'
else
SET #CODESTR = #CODESTR + '(max)'
end --those with(200)
else
begin
SET #CODESTR = #CODESTR --DO NOTHING
end
END --IF #MaxLength IS NOT NULL
IF #IsNullable = 1
SET #CODESTR = + #CODESTR + ' = NULL '
if #IsPrimaryKey = 1
SET #CODESTR = #CODESTR + ' OUTPUT '
if #CurrentDelimiterPositionVar <> #Count
SET #CODESTR = #CODESTR + ','
--DEBUGGING
--set #CODESTR = #CODESTR + '#ColumnName - ' + #ColumnName
--set #CODESTR = #CODESTR + '#DataType - ' + #DataType
--set #CODESTR = #CODESTR + '#IsNullable - ' + #IsNullable
--set #CODESTR = #CODESTR + '#MaxLength - ' + CONVERT ( VARCHAR , #MaxLength )
set #CODESTR = #CODESTR + CHAR(13)
SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
END
SET #CODESTR = #CODESTR + '
WITH EXECUTE AS CALLER
AS
BEGIN -- proc start
SET NOCOUNT ON;
BEGIN TRY --begin try
--
set #Ret = 1 --assume false from the beginning
declare #MsgKey [nvarchar](max)
declare #MsgTxt [nvarchar](max)
exec procUtils_GetMsgTxtByKeyAndUserSessionId
#UserSessionId =2 ,
#MsgKey = ''MsgOkTheAddingOfItemIsOk'' ,
#MsgTxt = ''''
set #MsgOut = replace (#MsgTxt , ''{0}'' , ''' + #TableName + ''' )
declare #thisProcName varchar(300)
set #thisProcName= ( SELECT OBJECT_NAME(##PROCID))
'
SET #CurrentDelimiterPositionVar = 1 --START LOOP AGAIN
set #CODESTR = #CODESTR + '
--Action !!!
INSERT INTO [dbo].[' + #TableName + ']( ' + CHAR(13)
--Loop through until all row processing is done
WHILE #CurrentDelimiterPositionVar <= #Count --2nd loop
BEGIN
--Load current value from the Table
SELECT #ColumnName = ColumnName FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #DataType = DataType FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #MaxLength = MaxLength FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
set #IsNullable = ( select IsNullable FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
if #IsPrimaryKey = 1
begin -- the primary key
set #PkColumnName = #ColumnName
end --the primary key
if ( #DataType = 'timestamp' or #IsComputed = 1 or #IsPrimaryKey = 1 )
begin
set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
continue
end
--select
if #CurrentDelimiterPositionVar <= #Count
BEGIN
set #CODESTR = #CODESTR + '[' + #ColumnName + ']' --null the codestring var
if #CurrentDelimiterPositionVar <> #Count
set #CODESTR = #CODESTR + ', --type of ' + #DataType + CHAR(13) --WITH COMMA
ELSE
set #CODESTR = #CODESTR + ' --type of ' + #DataType + CHAR(13) --NO COMMA
END -- IF SHOULD PRINT COLUMN
SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1;
END --eof while 2
set #CODESTR = #CODESTR + ') VALUES ( '
--AND START ALL OVER AGAIN
SET #CurrentDelimiterPositionVar = 1
--Loop through until all row processing is done
WHILE #CurrentDelimiterPositionVar <= #Count --WHILE 3
BEGIN
--Load current value from the Table
SELECT #ColumnName = ColumnName FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #DataType = DataType FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
SELECT #MaxLength = MaxLength FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar
set #IsNullable = ( select IsNullable FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
set #IsPrimaryKey = ( select IsPrimaryKey FROM #ColumnNames
WHERE Number = #CurrentDelimiterPositionVar )
if ( #DataType = 'timestamp' or #IsComputed = 1 or #IsPrimaryKey = 1)
begin
set #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1
continue
end
set #CODESTR = #CODESTR + '#' + #ColumnName
if #CurrentDelimiterPositionVar <= #Count
BEGIN
IF #CurrentDelimiterPositionVar <> #Count
set #CODESTR = #CODESTR + ' , --type of ' + #DataType --all others with comma
else
set #CODESTR = #CODESTR + ' --type of ' + #DataType --the last one without comma
END -- IF SHOULD NOT PRINT COLUMN
--increase the counter
set #CODESTR = #CODESTR + CHAR(13)
SET #CurrentDelimiterPositionVar = #CurrentDelimiterPositionVar + 1;
END
set nocount off
SET #CODESTR = #CODESTR + ')
SET #' + #pkColumnName + ' = ##IDENTITY
set #Ret = ##ERROR
set #DebugMsgOut = ''TODO:REMOVE INSERT OK ''
END TRY
BEGIN CATCH
EXEC #ret = [dbo].[procUtils_GetMsgTxtByKeyAndUserSessionId]
#UserSessionId = 2,
#MsgKey = N''ErrorMsgMenuRetrievalFailed'',
#MsgTxt = #MsgOut OUTPUT
set #ret = 1
set #msgOut = #MsgTxt
set #debugMsgOut = '' Error number: '' + CAST(ERROR_NUMBER() AS varchar(100)) +
''Error message: '' + ERROR_MESSAGE() + ''Error severity: '' +
CAST(ERROR_SEVERITY() AS varchar(10)) +
''Error state: '' + CAST(ERROR_STATE() AS varchar(100)) +
''XACT_STATE: '' + CAST(XACT_STATE() AS varchar(100))
-- record the error in the database
set #debugMsgOut = #debugMsgOut + #msgOut
INSERT INTO [dbo].[LogStore] ( [Date],[Thread],[Level],[Logger],[Message])
values ( getdate() , N''8'', N''DEBUG'', #thisProcName , #debugMsgOut )
END CATCH
END --procedure end
GO
'
print #codestr
END TRY --end try
BEGIN CATCH
print ' Error number: ' + CAST(ERROR_NUMBER() AS varchar(100)) +
'Error message: ' + ERROR_MESSAGE() + 'Error severity: ' +
CAST(ERROR_SEVERITY() AS varchar(1000)) +
'Error state: ' + CAST(ERROR_STATE() AS varchar(100)) +
'XACT_STATE: ' + CAST(XACT_STATE() AS varchar(100))
END CATCH
END --procedure end
--USE [Gaf]
--GO
--SELECT NAME FROM SYS.tables where name like '%Msg%'
--EXEC [dbo].[procUtils_GenerateInsertProc] #TableName = N'Whatever'
GO

Error Pass from nested MSSQL procedure to parent procedure

I have one parent stored procedure and one nested stored procedure. Parent Stored procedure calls the nested stored procedure on loop. Now when there is certain condition matches I have raised the error. When this error is raised I want to stop all the process and return the error.
CREATE Proc [dbo].[Usp_GenSalarySheet](#SalData [HRM].UTDT_SalaryData ReadOnly)
AS
set nocount on
DECLARE #SMT NVARCHAR(MAX)
SET #SMT = 'Create Table ##SalarySheet (StaffID INT,FullName NVARCHAR(1024),PresentDays NVARCHAR(1024),Absent NVARCHAR(1024),Department NVARCHAR(1024),Designation NVARCHAR(1024),'
DECLARE #HopName nvarchar(max)
Declare HOPCursor cursor for select ID from HRM.tbl_HOP
OPEN HOPCursor
FETCH NEXT FROM HOPCursor INTO #HopName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SMT = #SMT + ' [' + #HopName + '] DECIMAL(19,7),'
FETCH NEXT FROM HOPCursor into #HopName
END
SET #SMT = #SMT + '[Total] DECIMAL(19,7))'
CLOSE HOPCursor
DEALLOCATE HOPCursor
print (#smt)
exec (#SMT)
select * into #temp from #SalData
Declare #TopID INT
While (Select Count(*) From #Temp) > 0
Begin
Select Top 1 #TopID = StaffID From #temp
Declare #StaffID INT =(select top 1 StaffID from #temp)
Declare #StaffName NVARCHAR(1024) = (SELECT TOP 1 FullName FROM #temp)
Declare #WorkingDays Int = (SELECT top 1 WorkingDays from #temp)
Declare #Leave INT = (SELECT top 1 [Absent] from #temp)
INSERT INTO ##SalarySheet(StaffID,FullName,[Absent]) values(#StaffID,#StaffName,#Leave)
DECLARE #HOPType INT
DECLARE #Value Decimal(19,7)
DECLARE #CalcVal DECIMAL(19,7) = 0
DECLARE #Formula NVARCHAR(MAX)
DECLARE #Total DECIMAL(19,7)
DECLARE #PayEvery INT
DECLARE #Round Int
Declare HOPList Cursor for SELECT ID,HOPType,Value,Formula,RoundOff,PayEvery FROM HRM.Tbl_HOP order by Schedule
open HOPList
FETCH NEXT FROM HOPList INTO #HopName,#HOPType,#Value,#Formula,#Round,#PayEvery
WHILE ##FETCH_STATUS = 0
BEGIN
if exists(select * from HRM.[Tbl_ContractHOPDetails] where PersonalDetailsID = #StaffID and HOPID = #HopName)
print('select * from HRM.[Tbl_ContractHOPDetails] where PersonalDetailsID = ' + convert(varchar(max), #StaffID) + ' and HOPID =' + convert(varchar(max),#HopName))
begin
if(#HOPType=51)
begin
exec HRM.Usp_GetSalaryValueFromFormula #StaffID,#Formula,#HOPType,#Leave,#WorkingDays,#Value output
set #HOPType= 50
end
if(#HOPType=50)
begin
set #CalcVal = #value
END
IF(#HOPType=38)
BEGIN
SET #CalcVal = #Value - ((#Value/#WorkingDays) * #Leave)
END
if(#PayEvery= 40)
begin
set #CalcVal = ((#CalcVal * #WorkingDays) - (#CalcVal * #Leave))
end
if(#Round = 45)
begin
set #CalcVal = round(#CalcVal,2)
end
else if(#Round = 46)
begin
set #CalcVal = CEILING(#CalcVal)
end
else if(#Round = 47)
begin
set #CalcVal = FLOOR(#CalcVal)
end
set #SMT ='UPDATE ##SalarySheet SET [' + #HopName + '] = ' + cast(#CalcVal as nvarchar(max)) + ' where StaffID = ' + cast(#StaffID as nvarchar(max))
exec (#smt)
end
SET #CalcVal = 0
FETCH NEXT FROM HOPList INTO #HopName,#HOPType,#Value,#Formula,#Round,#PayEvery
END
close HOPList
DEALLOCATE HOPList
set #SMT ='UPDATE ##SalarySheet SET [Total] = ' + cast(#Total as nvarchar(max)) + ' where StaffID = ' + cast(#StaffID as nvarchar(max))
exec (#smt)
Delete #temp Where StaffID = #TopID
end
select * from ##SalarySheet
drop table ##SalarySheet
This is my parent Stored Procudere and nested procedure is as follow:
CREATE proc [HRM].[Usp_GetSalaryValueFromFormula](#StaffID INT,#val nvarchar(max),#HOPType INT,#Leave INT,#WorkingDays INT, #GetResult Decimal(19,7) output)
as
set nocount on
Declare #Formula Varchar(max)
declare #initial INT =0
declare #final INT =0
Declare #DataVal NVARCHAR(MAX) -- set the value from HOP table
declare #FieldVal nvarchar(max)
declare #cnt int = 0
Declare #Complete Int =CHARINDEX ('[',#val,0)
while (#Complete <> 0)
begin
set #initial = CHARINDEX ('[',#val,0)
set #final = CHARINDEX(']',#val,0)
set #FieldVal = SUBSTRING(#val,#initial,(#final-#initial) + 1)
if len(#FieldVal)<>0
begin
select #HOPType = HOPType, #DataVal= ( case when HOPType = 51 then [Formula] else cast([Value] as nvarchar(max)) end) from HRM.Tbl_ContractHOPDetails where PersonalDetailsID = #StaffID and HOPID in(select ID from HRM.tbl_HOP where HOPName = replace(replace(#fieldVal,'[',''),']',''))
if (#DataVal is null or #DataVal ='')
begin
RAISERROR ('Nested HOP is not defined.',11,1)
RETURN
end
print(#DataVal)
if ISNUMERIC(#DataVal)=1
begin
if(#HOPType = 38)
begin
SET #DataVal = cast(#DataVal as decimal(19,7)) - ((cast(#DataVal as decimal(19,7))/#WorkingDays) * #Leave)
end
end
set #val = replace(#val,#fieldVal,#DataVal)
set #fieldVal= ''
set #DataVal = ''
end
set #Complete = CHARINDEX ('[',#val,0)
set #fieldVal =''
set #final =0
set #initial = 0
end
SET #Complete =CHARINDEX ('{',#val,0)
while (#Complete <> 0)
BEGIN
set #initial = CHARINDEX ('{',#val,0)
set #final = CHARINDEX('}',#val,0)
set #FieldVal = SUBSTRING(#val,#initial+1,(#final-#initial)-1)
if len(#FieldVal)<>0
begin
set #DataVal = isnumeric((SELECT 0 FROM [HRM].Tbl_StaffTag where CValue = #FieldVal and StaffID = #StaffID))
set #FieldVal = '{' + #FieldVal + '}'
set #val = replace(#val,#fieldVal,#DataVal)
set #fieldVal= ''
set #DataVal = ''
end
set #Complete = CHARINDEX ('{',#val,0)
set #final =0
set #initial = 0
END
DECLARE #RetrunVal DECIMAL(19,7)
declare #ParmDefinition Nvarchar(512) = '#GetVal decimal(19,7) OUTPUT'
Declare #SMT NVARCHAR(MAX) = ' SET #GetVal = ' + #val
EXECUTE sp_executeSQL #Smt, #ParmDefinition, #GetVal =#RetrunVal OUTPUT
set #GetResult = #RetrunVal
But in current situation it raises error and again from the main procedure it runs next step of loop. But I want to terminate the complete process after this raiserror
Kindly help me
My guess is that RaiseError throws the control back to the caller, which might make the Return statement unreachable. The caller (loop) continues with next iteration.

Looking for multiples substrings within a SQL string

I have several occurrences of differences strings in the columns, like this example
'dsasdasdsd'+'ewewewew'+'45454545'+(avg('uuuuuuu'))
I need to split this string into several columns with the substrings that are between
aphostropes
like this:
Column 1 = dsasdasdsd
Column 2 = ewewewew
Column 3 = 45454545
Column 4 = uuuuuuu
The numbers of apperances are random, thefore the length of the original column is also not fixed (from 50 char to > 1000)
DECLARE #InStr VarChar(1000) = '''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))'''
DECLARE #intStart INT = 0
DECLARE #intEnd INT = 1
DECLARE #ColNo INT = 1
DECLARE #MyString VARCHAR(2000)
DECLARE #SelectString VARCHAR(8000) = 'SELECT '
WHILE(#intStart < LEN(#InStr) )
BEGIN
SELECT #intStart = CHARINDEX(CHAR(39), #InStr, 0) + 1
SELECT #intEnd = CHARINDEX(CHAR(39), #InStr, #intStart)
SELECT #SelectString = #SelectString + CHAR(39) + SUBSTRING(#InStr, #intStart, #intEnd - #intStart) + CHAR(39) + ' As [Column ' + CAST(#ColNo As Varchar) + '],'
SELECT #InStr = SUBSTRING(#InStr, #intEnd + 1, LEN(#InStr)-#intEnd )
SET #ColNo = #ColNo +1
END
SELECT #SelectString = LEFT(#SelectString, Len(#SelectString) -1)
EXEC (#SelectString)
I have been playing with this and this does run but unfortunately I don't have time right now to carry on with it but maybe you can improve on this?
HTH
You can try this:
create table tSqlStrings (sText nvarchar(1000))
insert tSqlStrings values('''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))')
create table tResults (
sColumn1 nvarchar(1000)
,sColumn2 nvarchar(1000)
,sColumn3 nvarchar(1000)
,sColumn4 nvarchar(1000)
)
and
DELETE tResults
DECLARE #sText nvarchar(1000) = (
SELECT
sText
FROM
tSqlStrings
)
DECLARE #lBegin int = CHARINDEX('''',#sText)
DECLARE #lEnd int = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
DECLARE #sText0 nvarchar(1000)
DECLARE #sColumn1 nvarchar(1000)
DECLARE #sColumn2 nvarchar(1000)
DECLARE #sColumn3 nvarchar(1000)
DECLARE #sColumn4 nvarchar(1000)
DECLARE #iCnt int = 1
while #iCnt<=4
--(0<len(#sText) and 0<#lBegin and 0<#lEnd)
BEGIN
SET #sText0 = substring(#sText,#lBegin+1,#lEnd-2)
IF #iCnt=1 begin SET #sColumn1=#sText0 end
IF #iCnt=2 begin SET #sColumn2=#sText0 end
IF #iCnt=3 begin SET #sColumn3=#sText0 end
IF #iCnt=4 begin SET #sColumn4=#sText0 end
set #sText = substring(#sText,#lBegin + #lEnd+2,len(#sText))
SET #lBegin = CHARINDEX('''',#sText)
SET #lEnd = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
SET #iCnt = #iCnt+1
END
INSERT
tResults (sColumn1,sColumn2,sColumn3,sColumn4)
VALUES (#sColumn1,#sColumn2,#sColumn3,#sColumn4)
SELECT * FROM tResults
on sql fiddle
You will be able to achieve this using CHARINDEX() and SUBSTRING()
Following example shows for splitting to 2 columns. When it has more columns, query will be get little more complicated. However, you can follow this to build your query.
SELECT OriginalColumn
, SUBSTRING(OriginalColumn, 1,CHARINDEX('x',OriginalColumn,1)-1) AS Column1
, SUBSTRING(OriginalColumn, CHARINDEX('x',OriginalColumn,1) + 1 ,CHARINDEX('x',OriginalColumn,CHARINDEX('x',OriginalColumn,1)-1)) AS Column2
FROM YourTable
I have used "x" as the delimiter in the example. Following is a sample result
try this:
declare #delim char
set #delim = ''''
declare #str nvarchar(max)
declare #substr nvarchar(max)
declare #newstr nvarchar(max)
declare #tmpTable table (partStrings nvarchar(max))
declare #count int
set #count = 0
select #str = <***Your String***>
while(charindex(#delim,#str) != 0)
begin
set #count = #count + 1
Select #substr = substring(#str,1,charindex(#delim,#str)-1)
if((#count % 2) = 0)
begin
insert into #tmpTable values(#substr)
end
Set #newstr = substring(#str,charindex(#delim,#str)+1,len(#str)-charindex(#delim,#str))
set #str = #newstr
end
select partStrings from #tmpTable