How to loop the variables in t-sql - sql

I have a t-sql i have to loop the variables.
DECLARE #empno nVARCHAR(MAX),#tableHTML NVARCHAR(MAX) ;
set #empno = (select Employee_No from emptemp where active = 'Yes');
SET #tableHTML =
N'<H2>Additions</H2>' +
N'<table border="1">' +
N'<th>Ename</th>' +
N'<th>Sal</th>' +
'<tr>' +
CAST ( ( select td=ename,'',td=sal,'' from emp Where empno = #empno)
FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' ;
EXEC msdb.dbo.sp_send_dbmail
#recipients=someone#gmail.com,
#subject = emp ,
#body = #tableHTML , #body_format = 'HTML',
#profile_name = 'Sql Profile'
The Emptemp table looks like
id empno active
1 245 yes
2 124 yes
3 255 yes
4 224 No
I have to send the individual mail based on the data in emp table

That is how cursor will look like:
DECLARE #empno nVARCHAR(MAX)
DECLARE #tableHTML NVARCHAR(MAX) ;
DECLARE #ID INT;
DECLARE Curs CURSOR FAST_FORWARD
FOR
SELECT DISTINCT ID
FROM dEmptemp
WHERE active = 'Yes'
ORDER BY ID
OPEN Curs
FETCH NEXT FROM Curs INTO #ID
WHILE ##FETCH_STATUS = 0
BEGIN
set #empno = (SELECT empno FROM emptemp WHERE ID = #ID);
SET #tableHTML =
N'<H2>Additions</H2>' +
N'<table border="1">' +
N'<th>Ename</th>' +
N'<th>Sal</th>' +
'<tr>' +
CAST ( ( select td=ename,'',td=sal,'' from emp Where empno = #empno)
FOR XML PATH('tr'), TYPE ) AS NVARCHAR(MAX) ) + N'</table>' ;
EXEC msdb.dbo.sp_send_dbmail
#recipients=someone#gmail.com,
#subject = emp ,
#body = #tableHTML , #body_format = 'HTML',
#profile_name = 'Sql Profile'
FETCH NEXT FROM Curs INTO #ID
END
CLOSE Curs
DEALLOCATE Curs;

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 .

I am using cursor to fetch rows from a temp table but else if condtion is not working, is this a good approch to do these type of task on MSSQL?

i have a temp table having record id, module id and status id, now i have to check every row of that temp table and according to #levelid i have to update corresponding table with that status id,
but below code never goes to else if condition, i am new to mssql seeking for your valuable answers :)
DECLARE #MyCursor CURSOR;
DECLARE #LevleId INT,
#STATUS VARCHAR(max),
#RECID VARCHAR(max);
BEGIN
SET #MyCursor = CURSOR
FOR SELECT TOP 1000 level_id,
status_id,
record_id
FROM #temp_record_id_typ2
WHERE approval_typ_id = 2
OPEN #MyCursor
FETCH next FROM #MyCursor INTO #LevleId, #STATUS, #RECID
WHILE ##FETCH_STATUS = 0
BEGIN
IF ( #LevleId = 1
AND #STATUS != 3 )
BEGIN
SELECT #Update_Typ2_Rec = N'UPDATE hrms_approvals SET approval_status_id = ' +
#STATUS
+ ' WHERE record_id = ' + #RECID
+ ' AND module_id = ' + #Module_id +
' ';
--SELECT #Update_Typ2_Rec
EXECUTE Sp_executesql
#Update_Typ2_Rec;
SELECT #UPDATE_MODULE_TABLE = N'UPDATE ' + #TableName +
' SET approval_status_id = 9 WHERE id = '
+ #RECID + '';
--SELECT #UPDATE_MODULE_TABLE
EXECUTE Sp_executesql
#UPDATE_MODULE_TABLE;
PRINT 'LevleId = 1'
END
ELSE IF ( #LevleId = 2
AND #STATUS != 3 )
BEGIN
SELECT #Update_Typ2_Rec =
N'UPDATE hrms_approvals SET approval_status_id = '
+ #STATUS + ' WHERE record_id = '
+ #RECID + ' AND module_id = '
+ #Module_id + ' ';
--SELECT #Update_Typ2_Rec
EXECUTE Sp_executesql
#Update_Typ2_Rec;
SELECT
#UPDATE_MODULE_TABLE = N'UPDATE ' + #TableName
+ ' SET approval_status_id = 10 WHERE id = ' + #RECID + '';
--SELECT #UPDATE_MODULE_TABLE
EXECUTE Sp_executesql
#UPDATE_MODULE_TABLE;
PRINT 'LevleId = 2'
END
ELSE IF ( #LevleId = 3
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 3'
END
ELSE IF ( #LevleId = 4
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 4'
END
ELSE IF ( #LevleId = 5
AND #STATUS != 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 5'
END
FETCH next FROM #MyCursor INTO #LevleId, #STATUS, #RECID
END;
CLOSE #MyCursor;
DEALLOCATE #MyCursor;
END;
Try this below code,You didn't declare this Parameters "#TableName and #ModuleId", Check your code and assign the value for #TableName and #ModuleId
Declare #Counter int=1
,#Tot_Count int=0
,#LevleId int
,#Status int
,#RecId int
,#Module_id int
,#TableName varchar(30)=''
Create Table #Temp_Table
(
Id int identity(1,1)
,level_id int
,status_id int
,record_id int
,Module_id int
)
Insert into #Temp_Table
(
level_id,status_id,record_id
)
Select level_id
,status_id
,record_id
,Module_id
from #temp_record_id_typ2
where approval_typ_id = 2
Select #Tot_Count=Count(1) from #Temp_Table
While #Tot_Count >= #Counter
Begin
Select #LevleId=level_id
,#Status=status_id
,#RecId=record_id
,#Module_id=Module_id
from #Temp_Table
where Id=#Counter
IF ( #LevleId = 1 AND #STATUS <> 3 )
BEGIN
Exec
('
UPDATE hrms_approvals
SET approval_status_id = ' + #STATUS + '
WHERE record_id = ' + #RECID + '
AND module_id = ' + #Module_id +'
UPDATE '+ #TableName +'
SET approval_status_id = 9
WHERE id = '+ #RECID + '
')
PRINT 'LevleId = 1'
END
ELSE IF ( #LevleId = 3 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 3'
END
ELSE IF ( #LevleId = 4 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 4'
END
ELSE IF ( #LevleId = 5 AND #STATUS <> 3 )
BEGIN
SELECT #STATUS,
#LevleId
PRINT 'LevleId = 5'
END
Set #Counter+=1
End
Drop table #Temp_Table

SSIS package for replacing the stored procedure with cursor and different servers with join clauses

I am trying to create a ssis package for replacing the below stored procedures. It has join clauses, cursors and are using different servers. So I have been trying to figure out the solution for it. If anyone have any concepts so that I get rid of the linked server connection issue. Thank you in advance. Any kind of useful steps and hints. I really appreciate it.
ALTER PROCEDURE [dbo].[AUDIT_FILES] AS
SET NOCOUNT ON
DECLARE
#cmd nvarchar(4000)
, #working_dir nvarchar(240)
, #file_name nvarchar(240)
, #file_list nvarchar(2000)
, #table_name sysname
, #audit_count int
, #email_to nvarchar(MAX)
, #email_subject nvarchar(240)
, #email_body nvarchar(MAX)
, #email_attach nvarchar(240)
, #top_recs int
, #sql nvarchar(MAX);
BEGIN TRY
SET #working_dir = 'k:\sql\data\WWE037\audit';
SET #cmd = 'del /q "' + #working_dir + '*.*"';
EXEC sys.xp_cmdshell #cmd, NO_OUTPUT;
IF CURSOR_STATUS('global','c_audit_tables') > -1 DEALLOCATE c_audit_tables;
DECLARE c_audit_tables CURSOR
FOR
SELECT
a.TABLE_NAME
, a.TOP_NUM_REC
FROM
[CSVP0007\WWE037].Audit.INFORMATION_SCHEMA.TABLES i
INNER JOIN WebPM_Copy.dbo.AUD_TABLE_LIST a ON
i.TABLE_NAME = a.TABLE_NAME
INNER JOIN [CSVP0007\WWE037].Audit.sys.tables t on
a.TABLE_NAME = t.name
INNER JOIN [CSVP0007\WWE037].Audit.sys.partitions p ON
p.object_id = t.object_id
GROUP BY a.TABLE_NAME, a.TOP_NUM_REC
HAVING SUM(rows) > 1
ORDER BY 1;
OPEN c_audit_tables;
FETCH c_audit_tables INTO #table_name, #top_recs;
WHILE ##fetch_status = 0
BEGIN
SET #file_name = #table_name + '.txt';
SET #audit_count = COALESCE(#audit_count,0) + 1;
SET #cmd = 'SELECT TOP {Recs} * INTO dbo.TMP_AUDIT_EXPORT FROM
[CSVP0007\WWE037].Audit.dbo.{TableName}';
SET #cmd = REPLACE(#cmd,'{Recs}',#top_recs);
SET #cmd = REPLACE(#cmd,'{TableName}',#table_name);
IF OBJECT_ID('TMP_AUDIT_EXPORT') IS NOT NULL
DROP TABLE TMP_AUDIT_EXPORT;
EXEC sys.sp_executesql #cmd;
EXEC util.dbo.usp_export_table
#db_name = 'wb_Copy'
, #schema_name = 'dbo'
, #table_name = 'TMP_AUDIT_EXPORT'
, #output_dir = #working_dir
, #output_file = #file_name
, #delimiter = '|'
, #use_native_mode = 0
, #location_code = 'DEV_Wb_COPY';
FETCH c_audit_tables INTO #table_name, #top_recs;
END
CLOSE c_audit_tables;
DEALLOCATE c_audit_tables;
SET #file_name = 'Audit_FCL_' + CONVERT(CHAR(8),GETDATE(),112) + '.zip';
SET #file_list = #working_dir + '\*.txt';
EXEC BIA_Utils_User.dbo.usp_zip_files
#zip_dir = #working_dir
, #zip_file = #file_name
, #file_list = #file_list
, #zip_password = NULL;
SET #email_subject = 'Wb Daily Audit Testing: ' + CONVERT(VARCHAR,
GETDATE(), 101)
SET #email_attach = #working_dir + '\' + #file_name;
PRINT #email_attach
SET #email_body = '*** Number of Audit File(s) To Be Reviewed: ' +
CONVERT(NVARCHAR,#audit_count);
EXEC Utils_User.dbo.usp_send_bia_mail
#profile_name = 'WB'
, #subject = #email_subject
, #body = #email_body
, #body_format = 'TEXT'
, #importance = 'NORMAL'
, #file_attachments = #email_attach
, #app_code = 'wb_app'
, #bnotify_app_group = 'Audit_Email';
END TRY

Send sp_send_dbmail only if results are available

I want to send an e-mail from my database only if the executed query has output and is not empty.
I was wondering how I can do this and where to embed this into my code. On top of my head, I thought of counting the results and having count > 0 or maybe something with the query in conjunction with ##rowcount > 0. What would you suggest?
Here is my code:
ALTER proc dbo.spBornBefore2000 as
set nocount on
DECLARE #sub VARCHAR(100),
#qry VARCHAR(max),
#msg VARCHAR(250),
#query NVARCHAR(max),
#tab char(1) = CHAR(9)
SELECT #sub = 'before 1990 -' + cast(getdate() as varchar(100))
SELECT #msg = N'blablabla.....'
SELECT #query = ' select id, name, dob, year(dob) as birth_year
from people
where year(dob) < 2000 '
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'USERS',
#recipients = 'abc#gmail.com',
#body = #msg,
#subject = #sub,
#query = #query,
#query_attachment_filename = 'before2000.csv',
#attach_query_result_as_file = 1,
#query_result_header = 1,
#query_result_width = 256 ,
#query_result_separator = #tab,
#query_result_no_padding =1;
You can do something like this:
EXEC(#query)
IF ##ROWCOUNT > 0
BEGIN
-- send email here
END
ALTER proc dbo.spBornBefore2000 as
set nocount on
DECLARE #sub VARCHAR(100),
#qry VARCHAR(max),
#msg VARCHAR(250),
#query NVARCHAR(max),
#tab char(1) = CHAR(9)
SELECT #sub = 'before 1990 -' + cast(getdate() as varchar(100))
SELECT #msg = N'blablabla.....'
SET #query = ' select id, name, dob, year(dob) as birth_year
from people
where year(dob) < 2000 '
IF EXISTS (select id, name, dob, year(dob) as birth_year
from people
where year(dob) < 2000)
begin
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'USERS',
#recipients = 'abc#gmail.com',
#body = #msg,
#subject = #sub,
#query = #query,
#query_attachment_filename = 'before2000.csv',
#attach_query_result_as_file = 1,
#query_result_header = 1,
#query_result_width = 256 ,
#query_result_separator = #tab,
#query_result_no_padding =1;
end
ELSE
begin
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'USERS',
#recipients = 'myself#gmail.com',
#body = 'No results returned'
end

How to split and replace with stored procedure?

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.