I want to give information according to profession using 'Trigger' - sql

'Trigger' I want to give information according to the profession using. For example; When I entered the engineer I added 'engineer'. This is his name and surname. ' as.
ALTER TRIGGER tigger_example
ON information
AFTER INSERT
AS
IF EXISTS(SELECT * FROM inserted WHERE Person_Job='Engineer')
BEGIN
PRINT 'Engineer added to list.'+
'Person Info:' +
'Name : ' + person_firstname + -- not work
'Surname : ' + person_lastname -- not work
END
ELSE IF EXISTS(SELECT * FROM inserted WHERE Person_Job='Architect')
BEGIN
PRINT 'Architect added to list.'+
'Person Info:' +
'Name : ' + person_firstname + -- not work
'Surname : ' + person_lastname -- not work
END
ELSE
BEGIN
PRINT 'An undefined contact has been added to the list.'
END
ERROR:
The name "person_firstname" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.

You have to use "SELECT ... from inserted" for read field value.
example:
ALTER TRIGGER tigger_example
ON information
AFTER INSERT
AS
DECLARE #MSG NVARCHAR(MAX)
IF EXISTS(SELECT * FROM inserted WHERE Person_Job='Engineer')
BEGIN
SET #MSG ='Engineer added to list.'+CHAR(13)+CHAR(10)+'Person Info:'
SELECT #MSG=#MSG+CHAR(13)+CHAR(10)+'Name : ' + person_firstname + 'Surname : ' + person_lastname
FROM inserted WHERE Person_Job='Engineer'
print #MSG
END
ELSE IF EXISTS(SELECT * FROM inserted WHERE Person_Job='Architect')
BEGIN
SET #MSG ='Architect added to list.'+CHAR(13)+CHAR(10)+'Person Info:'
SELECT #MSG=#MSG+CHAR(13)+CHAR(10)+'Name : ' + person_firstname + 'Surname : ' + person_lastname
FROM inserted WHERE Person_Job='Architect'
print #MSG
END
ELSE
BEGIN
PRINT 'An undefined contact has been added to the list.'
END

Related

Trouble replacing abbreviated text correctly in SQL

I am trying to replace a bunch of difficult to decipher abbreviations with corresponding detailed descriptions. I have a table called Abbreviations that simply holds a list of abbreviations to look for and the corresponding descriptions they should be changed to. Additionally the "Replaced" table holds a list of unaltered abbreviated descriptions that I would like to change in a single column called "DescriptionCodes"
The data I am trying to change is a list of different teas. For instance the entry
"TADIN H-B GR" would be the abbreviation for "TADIN HERBAL BAG GREEN"
The SQL Code I am currently using looks like this:
BEGIN TRANSACTION
DECLARE #Desc varchar(500)
DECLARE #Abbr varchar(500)
DECLARE contact_cursor CURSOR FOR
SELECT Description, Abbrv FROM dbo.Abbreviations
OPEN contact_cursor
FETCH NEXT FROM contact_cursor
INTO #Desc, #Abbr
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT 'Changing ' + #Abbr + ' to ' + #Desc
UPDATE Replaced
SET DescriptionCodes = REPLACE(DescriptionCodes, #Abbr, #Desc)
WHERE DescriptionCodes LIKE CONCAT('% ', #Abbr, ' %')
FETCH NEXT FROM contact_cursor
INTO #Desc, #Abbr
END
CLOSE contact_cursor
DEALLOCATE contact_cursor
COMMIT
Of course the problem I am running into is that once an abbreviation is applied the detailed description may contain a substring that matches another abbreviation that is then applied. For instance PKG might be changed to PACKAGE but PA is the abbreviation for PINEAPPLE as well, meaning that once that change is applied the final result would be PINEAPPLECKAGE. Every abbreviation has a single blank space on either side so I thought to use that fact to not update any abbreviation without a blank space on either side, hence the
CONCAT('% ', #Abbr, ' %') in my code. However, when I try this method basically nothing gets changed at all. I've been able to see limited success by removing that constraint but the other issue then happens. Any ideas as to how I could make sure that only occurrences of abbreviations with a blank space on either side are considered and updated?
UPDATE:
After trying several of the solutions posted here, I still haven't been able to get it to work and I'm not sure why. By all appearances this is correct. Here is a sample of some of the data I'm working with:
JUSTEA HBL PKG CMCL CHM LG LR 1.5OZ
PRIDE OF INDIA BG ASM B BKFST 25 CT
CTL BR H-B 7BLSM PP 1 CT
POSTI H-B HRH CRN 20 CT
DRS H-B EPGP LPLDS PTVP TGN 20 CT
ULTLC BG CHG 100 CT
PG TIPS BG D B 40 CT
RPBL R-B B HLDY FT BLD 6 CT
This is fine and looks like it should convert with no issues. Yet when I run the code with spaces indicated (As with "LIKE '% ' + #Abbr + ' %'", which was my first inclination) the data remains completely unchanged. If I remove them the data becomes completely unintelligible. For example the line beginning with PRIDE OF INDIA becomes
PRIDE OF INDIA(N) IRISH AFTERNOON BLACK AG ASIA PLUM RICOT SPICE(D) EARMINT BLACK BLACK KFST 25 CURRANT AN AID N T
I feel I should note that this data was imported from Excel Spreadsheets originally. Is there any chance that has anything to do with the spaces not being recognized?
Why use "LIKE" if you're going to add the spaces? just do:
WHERE DescriptionCodes = #Abbr
You can do this and it will achieve what you are trying to do:
LIKE '% ' + #Abbr + ' %'
I think you need to update each record of the Replaced table multiple times, and you need to consider the 4 locations of the abbreviations (Alone, First, In the middle, Last). Something like this:
DECLARE #Replaced TABLE ([DescriptionCodes] varchar(50))
DECLARE #Abbreviations TABLE ([Abbrv] varchar(50), [Description] varchar(50))
INSERT INTO #Replaced([DescriptionCodes]) VALUES ('TADIN H-B GR')
INSERT INTO #Replaced([DescriptionCodes]) VALUES ('PKG')
INSERT INTO #Replaced([DescriptionCodes]) VALUES ('PKG PA')
INSERT INTO #Abbreviations([Abbrv], [Description]) VALUES ('H-B', 'HERBAL BAG')
INSERT INTO #Abbreviations([Abbrv], [Description]) VALUES ('GR', 'GREEN')
INSERT INTO #Abbreviations([Abbrv], [Description]) VALUES ('PKG', 'PACKAGE')
INSERT INTO #Abbreviations([Abbrv], [Description]) VALUES ('PA', 'PINAPPLE')
DECLARE #RowCount int;
WHILE 1 = 1
BEGIN
SET #RowCount = 0;
UPDATE r
SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], a.[Abbrv], a.[Description])
FROM #Replaced r join #Abbreviations a ON r.[DescriptionCodes] = a.[Abbrv];
SET #RowCount = #RowCount + ##RowCount;
UPDATE r
SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], ' ' + a.[Abbrv] + ' ', ' ' + a.[Description] + ' ')
FROM #Replaced r join #Abbreviations a ON r.[DescriptionCodes] like '% ' + a.[Abbrv] + ' %';
SET #RowCount = #RowCount + ##RowCount;
UPDATE r
SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], ' ' + a.[Abbrv],' ' + a.[Description])
FROM #Replaced r join #Abbreviations a ON r.[DescriptionCodes] like '% ' + a.[Abbrv];
SET #RowCount = #RowCount + ##RowCount;
UPDATE r
SET r.[DescriptionCodes] = REPLACE(r.[DescriptionCodes], a.[Abbrv] + ' ', a.[Description] + ' ')
FROM #Replaced r join #Abbreviations a ON r.[DescriptionCodes] like a.[Abbrv] + ' %';
SET #RowCount = #RowCount + ##RowCount;
IF #ROWCOUNT = 0 BREAK;
END
SELECT * FROM #Replaced

Adding a space to the data

I have a stored procedure like the following:
declare #mySymbol as varchar(32)
DECLARE #RefGroupID AS VARCHAR(20)
declare #myJID as varchar(45)
declare Div_csr cursor for
select distinct Symbol2, RefGroupID, jnl_id
from #TDRows td
WHERE TD_CompanyCode_AU = 'A'
open Div_csr
fetch next from Div_csr into #mySymbol, #RefGroupID, #myJID
while ##FETCH_STATUS = 0 begin
SET #InfoMessage = #InfoMessage +CONVERT(varchar(30),getdate(), 120)+ ' ' + #SPname
+ ': RefGroupID:'+ convert(varchar(20),#RefGroupID,101)
+ ' Sym: ' + #mySymbol
+ ' JID: ' + #myJID
+ CHAR(13) + CHAR(10)
fetch next from Div_csr into #mySymbol, #RefGroupID, #myJID
end
close Div_csr
deallocate Div_csr
#mySymbol is the data I want to modified.
For example; #mySymbol is BXP PRB. You can see there is a space between BXP and PRB. I want to this space also show in the comment that was created using the stored procedure.
Right now, the commment's Sym: is parsed by data #mySymbol. But it does not have space now. I do not know why.. .
The comment looks like this:
"DIV2PAY Record receipt from CSH RecordDt=08/04/2017 Intended PayDt= 08/15/2017 Sym=BXPPRB Qty=-100 CashRate=0.328125 Kind= Cash Dividend RowID= 127278 CAEventID= 105226767
".
Could anyone help me with this?

Getting various errors using dynamic SQL

SET #SQLSTATEMENT = 'INSERT INTO #MAX_STORAGE
SELECT MAX(A.[ROW])
FROM
(SELECT *
FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED]
WHERE
[FIPST_ENT] = ' + #FIPST_ENT + '
AND [FIPCNTY_ENT] = ' + #FIPCNTY_ENT + '
AND [SIC_ENT] = ' + #SIC2_ENT + '
AND [FMSZ_ENT] = ' + #FMSZENT_ENT + '
AND [ESTABLISHMENTS_AVAILABLE_FMSZEST <= ' + #MAXIMUM_FMSZEST+'] > 0) A'
EXEC(#SQLSTATEMENT)
I was running the dynamic SQL query above as part of a stored procedure I had written and got the following error:
Msg 207, Level 16, State 1, Line 7
Invalid column name 'A'.
I then changed my query so that it looked like this (eliminated the alias A):
SET #SQLSTATEMENT =
'INSERT INTO #MAX_STORAGE
SELECT
MAX([ROW])
FROM
(SELECT *
FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED]
WHERE [FIPST_ENT] = ' + #FIPST_ENT + '
AND [FIPCNTY_ENT] = ' + #FIPCNTY_ENT + '
AND [SIC_ENT] = ' + #SIC2_ENT + '
AND [FMSZ_ENT] = ' + #FMSZENT_ENT + '
AND [ESTABLISHMENTS_AVAILABLE_FMSZEST <= ' + #MAXIMUM_FMSZEST + '] > 0)'
EXEC(#SQLSTATEMENT)
But I still ran into an error (this time different):
Msg 102, level 15, state 1, line 9
Incorrect syntax near ')'
I declared the following variables earlier in the procedure with their respective data types/lengths seen next to them:
#FIPST_ENT CHAR(2)
#FIPCNTY_ENT CHAR(3)
#SIC2_ENT CHAR(2)
#FMSZENT_ENT CHAR(1)
#MAXIMUM_FMSZENT CHAR(1)
#SQLSTATEMENT VARCHAR(MAX)
Before this dynamic SQL statement was reached in the stored procedure, the temporary table #MAX_STORAGE was already created and contains only one column of datatype int.
Am I missing something I'm doing wrong? Any help would be greatly appreciated.
Thanks.
At bare minimum, you need to enclose string fields in escaped-single-quotes within the Dynamic SQL. The adaptation I show below is based on this comment on the Question:
FIPST_ENT is numeric in nature (i.e. 01-50) but cast as a character. Likewise with the other FIPCNTY_ENT and SIC2_ENT. FMSZENT is cast as a character but is sometimes numeric (i.e. 1-9) and other times non-numeric (i.e. A-C).
So it seems that only FMSZENT needs the escaped-single-quotes.
Also, using a derived query requires an alias. So whatever the initial problem was, you then introduced a new parse error by removing the alias ;-).
SET #SQLSTATEMENT =
'INSERT INTO #MAX_STORAGE
SELECT MAX(tmp.[ROW]) FROM
(SELECT * FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED]
WHERE [FIPST_ENT] = '+#FIPST_ENT+'
AND [FIPCNTY_ENT] = '+#FIPCNTY_ENT+'
AND [SIC_ENT] = '+#SIC2_ENT+'
AND [FMSZ_ENT] = '''+#FMSZENT_ENT+'''
AND [ESTABLISHMENTS_AVAILABLE_FMSZEST<='+#MAXIMUM_FMSZEST+'] > 0) tmp;'
Now, when it comes to debugging Dynamic SQL, the first step should be looking at what SQL you actually constructed, as it might not be what you think it should be:
PRINT #SQLSTATEMENT;

Using carriage return or line feed to build message body with tsql

I have the following tsql that sends db mail. This works with one formatting exception. The last two lines generated do not have a line feed or carriage return in the email body. The data types are varchar(255) and varchar(300) respectively.
I have tried with and with out cast and I have tried CHAR(10), CHAR(13) separately and together.
Why does these last two NOT split into separate lines?
DECLARE #errMsg VARCHAR(max)
-- review edit fact UMDNSID values and catch orphans with out parents in CategoryList
select #errMsg =
'====================================================================' + char(10) +
'Orphan UMDNSID: ' + cast(ef.umdnsid as varchar(50)) + char(10) +
'Edit Fact VendorItemID: ' + cast(ef.vendoritemid as varchar(50)) + char(10) +
'Current VendorItem UMDNSID: ' + cast(ip.umdnsid as varchar(50)) + char(10) +
'Current VendorItem Category: ' + ipcl.categoryname + char(10) +
'Item Description: ' + ef.LongDescription + char(10) + char(13)
from EditFact ef
join itemprovider ip
on ef.vendoritemid = ip.itemprovider_pk
join categorylist ipcl
on ipcl.umdnsid = ip.umdnsid
where 1=1
AND editstatusid = 0
AND settled is null
AND ef.UMDNSID not in (
select umdnsid from categorylist)
EXEC dbo.ProcessFile_SendMail #ProcessFile_id=0, #Subject='Orphan UMDNSID', #Message=#errMsg, #To='someone#email.com';
The email body ends up looking like the following and I expect a new line where you see **.
Orphan UMDNSID: 27854
Edit Fact VendorItemID: 4654178
Current VendorItem UMDNSID: 99936
Current VendorItem Category: Custom Packs **Item Description: TRAY CARDIAC CATH CUSTOM
In case that was the final answer
Test a print(#errMsg).
The problem may be in ProcessFile_SendMail.

tsql Loop with external query

I am looping through all my databases and aggregating the results into an aggregates database.
In my loop I call
master.dbo.xp_cmdshell osql C:\whatever.SQL
As the loop progresses, the cmdshell takes longer and longer to execute. If I stop the loop and run a single aggregate for one database it executes quickly.
Is there anything I can add to my external SQL script to make it run faster? Maybe something to commit and free the records before the next loop? Or should I add some kind of a pause after every loop?
I want to use an external SQL file because it contains many update statements and it's more manageable for me.
Here's how I loop:
Update dbFoo.dbo.tblBar set Processed = 0
Go
WHILE EXISTS ( SELECT ID FROM dbFoo.dbo.tblBar WHERE Processed = 0)
BEGIN
SELECT #aRow = MIN(tblBar.ID) FROM dbFoo.dbo.tblBar
SELECT #aFoo1 = Foo1 FROM dbFoo.dbo.tblBar WHERE ID = #aRow
SELECT #aFoo2 = Foo2 FROM dbFoo.dbo.tblBar WHERE ID = #aRow
SELECT #aFoo3 = Foo3 FROM dbFoo.dbo.tblWhatever WHERE Foo = #aFoo
EXEC RunPreAgg #Foo1 = #aFoo1, #Foo2 = #aFoo2, #Foo3 = #aFoo3, #RetVal = #aRetVal OUTPUT
SELECT returning = #aRetVal
UPDATE dbFoo.dbo.tblBar SET Processed = 1 WHERE ID = #aRow
END
Then the RunPreAgg stored procedure basically does this:
if db_id('db' + #Foo1 + '_' + #Foo2) is not null
BEGIN
--This bat file creates the SQL File
select #sql = 'master.dbo.xp_cmdshell '''+#path+'wwwRunPreAgg.bat ' + #Foo1 + ' ' + #Foo2 + ' ' + #Foo3 + ''''
exec( #sql )
--execute
select #sql = 'master.dbo.xp_cmdshell ''osql -E -o '+#path+'output\tmp'+#Foo1+'_'+#Foo2+'.txt -i '+#path+'tmp' + #Foo1 + '.SQL'''
exec( #sql )
--This erases the SQL File
select #sql = 'master.dbo.xp_cmdshell '''+#path+'wwwCleanup.bat ' + #Foo1 + ' ' + #Foo2 + ''''
exec( #sql )
Set #retval = 'Done!'
END
ELSE
BEGIN
Set #retval = 'Err: No DataBase'
END
The variable names are changed to protect the innocent. The code works fine, I just need to optimize.
If it is the loops performance that is causing you trouble, you might try reducing the number of selects. Normally I dislike Cursors, but your loop might benefit from one. You can select all the values you need for the loop into memory, then loop through those values without having to run 3 or 4 selects per loop (of course if the performance hit is occurring inside the RunPreAgg SP, then this won't help):
DECLARE cFoos CURSOR FOR
SELECT tblBar.ID, tblBar.Foo1, tblBar.Foo2, tblWhatever.Foo3
FROM dbFoo.dbo.tblBar
INNER JOIN dbFoo.dbo.tblWhatever
ON tblWhatever.Foo = tblBar.Foo
WHERE tblBar.Processed = 0;
OPEN cFoos;
FETCH NEXT FROM cFoos INTO #aRow, #aFoo1, #aFoo2, #aFoo3;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC RunPreAgg #Foo1 = #aFoo1, #Foo2 = #aFoo2, #Foo3 = #aFoo3, #RetVal = #aRetVal OUTPUT
SELECT returning = #aRetVal
UPDATE dbFoo.dbo.tblBar SET Processed = 1 WHERE ID = #aRow
FETCH NEXT FROM cFoos INTO #aRow, #Foo1, #Foo2, #Foo3;
END
CLOSE cFoos;
DEALLOCATE cFoos;