I need to create a json object in a stored procedure based on input parameters. The following works, but it's not very elegant and I am looking for a more elegant solution.
-- adding log entry
declare #logjson nvarchar(max);
set #logjson = concat( '{"InputParameters":[', '{');
set #logjson = concat(#logjson, '"MacOwner":"', #Owner, '",');
set #logjson = concat(#logjson, '"EMS":"', #EMS, '",');
set #logjson = concat(#logjson, '"AXBomId":"', #AXBomId, '",');
set #logjson = concat(#logjson, '"Serial":"', #SerialId, '",');
set #logjson = concat(#logjson, '"Device":"', #AXItem, '",');
set #logjson = concat(#logjson, '"HWDevice":"', #HWDevice, '",');
set #logjson = concat(#logjson, '"TestPCHostName":"', #TestPCHostName, '",');
set #logjson = concat(#logjson, '"TestSWVersion":"', #TestSWVersion, '"'); --Last parameter no comma
set #logjson = concat(#logjson, '}],');
set #logjson = concat(#logjson, '"OutputParameters":[','{');
set #logjson = concat(#logjson, '"MACAddress":"', #MACAddress, '"');
set #logjson = concat(#logjson, '}');
set #logjson = concat(#logjson, ']' );
set #logjson = concat(#logjson, '}');
I tried to use the SELECT xxxxx FOR JSON AUTO - but this requires at least one table in the select statement.
You can select from a subquery. For example
declare #Owner varchar(5) ='ow123', #AXBomId int =11
select * from (
select #Owner as MacOwner, #AXBomId as AXBomId
) t
for json auto
returns
[{"MacOwner":"ow123","AXBomId":11}]
Related
If I use the parameters to set the value in order to update the fields, nothing has been updated, but if I assign the value to the field directly, everything works fine.
Here is my sql script with parameters that won't work:
DECLARE #ItemValue NUMERIC(2,1) = 0.0,
#ItemName NVARCHAR = NULL,
#RuleID INT,
#IsValid BIT
SET #ItemValue =9
SET #ItemName = 'chbWorkingTimePerDay'
SET #RuleID = 1
SET #IsValid = 1
UPDATE hrms.RuleValue
SET ItemValue = #ItemValue,
IsValid = #IsValid
FROM hrms.RuleItem RI
JOIN hrms.RuleValue RV
ON RI.RuleItemID = RV.RuleItemID
WHERE RI.ItemName = #ItemName
AND RV.RuleID = #RuleID
Here is my sql script without parameters that works:
UPDATE hrms.RuleValue
SET ItemValue = 8.0,
IsValid = 1
FROM hrms.RuleItem RI
JOIN hrms.RuleValue RV
ON RI.RuleItemID = RV.RuleItemID
WHERE RI.ItemName = 'chbWorkingTimePerDay'
AND RV.RuleID = 1
#ItemName NVARCHAR = NULL will translate to #ItemName NVARCHAR(1) = NULL, which will cut off the string. You need to set NVARCHAR size.
So use:
#ItemName NVARCHAR(100) = NULL
instead of:
#ItemName NVARCHAR= NULL
SqlFiddle is available here.
I am trying to do a lookup to two different data extensions in exact target using ampscript. Please find the sample code I am trying .
%%[
Var #rows
Set #rows=LookupRows("DataExtensionOne","Lead Owner","Nick")
FOR #y = 1 TO RowCount(#rows) DO
Set #currentRow = Row(#rows,#y)
Set #value = FIELD(#currentRow ,"LeadId")
Set #secondDERows = LookupRows("DataExtensionTwo","Gender","Male")
FOR #x = 1 TO RowCount(#secondDERows) DO
Set #currentRowInSecDE = Row(#secondDERows,#x)
Set #secValue = FIELD(#currentRowInSecDE ,"LeadId")
IF #value == #secValue THEN
Set #FirstName = FIELD(#currentRowInSecDE ,"FirstName")
/* Need to break out of the loop */
]%%
The If condition check seems to fail #value == #secValue .
It doesnt fetch any value for the #FirstName. And what statement should be used to break out of IF loop ?
Has anyone come across similar problems ? Please do let me know.
As far as I am aware, ampscript does not have a break operator.
In this case, I would set up a boolean value that is checked to be false at the start of each loop and is set to True when you find a match. This way once you have matched you'll still run through the rest of the loop but noting will happen within them.
%%[
Var #rows
Set #found_result = False
Set #rows=LookupRows("DataExtensionOne","Lead Owner","Nick")
FOR #y = 1 TO RowCount(#rows) DO
if not #found_result then
Set #currentRow = Row(#rows,#y)
Set #value = FIELD(#currentRow ,"LeadId")
Set #secondDERows = LookupRows("DataExtensionTwo","Gender","Male")
FOR #x = 1 TO RowCount(#secondDERows) DO
if not #found_result then
Set #currentRowInSecDE = Row(#secondDERows,#x)
Set #secValue = FIELD(#currentRowInSecDE ,"LeadId")
IF #value == #secValue THEN
Set #FirstName = FIELD(#currentRowInSecDE ,"FirstName")
Set #found_result = True
ENDIF
endif
NEXT #x
endif
NEXT #y
]%%
%%[
Var #rows
Set #found_result = False
Set #rows=LookupRows("DataExtensionOne","Lead Owner","Nick")
FOR #y = 1 TO RowCount(#rows) DO
if #found_result == "TRUE" then
Set #currentRow = Row(#rows,#y)
Set #value = FIELD(#currentRow ,"LeadId")
Set #secondDERows = LookupRows("DataExtensionTwo","Gender","Male")
FOR #x = 1 TO RowCount(#secondDERows) DO
if #found_result == "TRUE" then
Set #currentRowInSecDE = Row(#secondDERows,#x)
Set #secValue = FIELD(#currentRowInSecDE ,"LeadId")
IF #value == #secValue THEN
Set #FirstName = FIELD(#currentRowInSecDE ,"FirstName")
Set #found_result = True
ENDIF
endif
NEXT #x
endif
NEXT #y
]%%
With this T-SQL query I define a variable #InDate with some date.
SET
#InDate = (SELECT MIN(bt.CreateDate) AS [INDATE]
FROM
mydatabase.dbo.BuyTransaction bt
LEFT JOIN
mydatabase.dbo.TransactionExtraFields tef ON bt.TransDocument = tef.TransDocument
AND bt.TransSerial = tef.TransSerial
AND bt.TransDocNumber = tef.TransDocNumber
AND ExtraFieldID = 1
WHERE
bt.TransDocument = 'FRM' AND tef.TextAnswer = #NumPI
AND bt.TransStatus = 0)
But now I need to change the Database name by another variable. I try something like that to make a string in a variable which will be executed
SET #InDate = '(SELECT MIN(bt.CreateDate) AS [INDATE]
FROM mydatabase.dbo.BuyTransaction bt
LEFT JOIN mydatabase.dbo.TransactionExtraFields tef ON bt.TransDocument = tef.TransDocument AND bt.TransSerial = tef.TransSerial AND bt.TransDocNumber = tef.TransDocNumber AND ExtraFieldID = 1
WHERE bt.TransDocument = ''FRM'' AND tef.TextAnswer = '''+#NumPI+''' AND bt.TransStatus = 0)'
EXECUTE #InDate
But my problem is how can I get the execute result into a variable again. Something like SET #InDate2 = EXECUTE #InDate is not working...
Any idea?
Use sp_executesql. I think the syntax in your case is something like:
declare #InDate date;
declare #sql nvarchar(max);
set #sql = N'SELECT #InDate = MIN(bt.CreateDate)
FROM mydatabase.dbo.BuyTransaction bt
LEFT JOIN mydatabase.dbo.TransactionExtraFields tef ON bt.TransDocument = tef.TransDocument AND bt.TransSerial = tef.TransSerial AND bt.TransDocNumber = tef.TransDocNumber AND ExtraFieldID = 1
WHERE bt.TransDocument = ''FRM'' AND tef.TextAnswer = '''+#NumPI+''' AND bt.TransStatus = 0';
exec sp_executesql #sql, N'#InDate date output', #InDate = #InDate output;
You can also make #NumPI a parameter as well.
The documentation for sp_executesql is here.
I have done this type of issue.
Please check the sample code. Its working for me. Please change according.
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #IntVariable INT
DECLARE #Lastlname varchar(30) = 'col10 ' -- this variable use for input in sp
SET #SQLString = N'SELECT #LastlnameOUT = '+#Lastlname+'
FROM TempStoreExcelData '
SET #ParmDefinition = N'#level tinyint,
#LastlnameOUT varchar(30) OUTPUT'
SET #IntVariable = 35
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#level = #IntVariable,
#LastlnameOUT=#Lastlname OUTPUT
SELECT #output = #Lastlname
select #output
EDIT
My previous posting on this subject involved specific transactions within the procedure which are no longer used and the error now only seems to occur in a very specific set of circumstances when I use an invalid user name to our companies email address badname#ourcompany.co.uk
The agent runs a stored procedure every ten minutes to send out emails. If it finds a new record then it sends a mail.
Noticed some strange behavior - if the TO field is correct but the BCC is an invalid email address but uses our valid company domain name (e.g. rubbishPart#ourcompany.co.uk) then the stored procedure sends out two emails to the TO. The domain name needs to be our company's domain name to get this behavior ...if I change the domain to gmail.com then only one mail goes out.
Why is this happening?
How do I change this behavior?
Is the Catch in this procedure redundant?
Here is the procedure:
BEGIN TRY
DECLARE #Exit TINYINT = 0
WHILE #Exit = 0
BEGIN
DECLARE #MailIdFound INT =
(
SELECT CASE
WHEN MIN(EmailId) IS NULL THEN 0
ELSE MIN(EmailId)
END
FROM WH.dbo.EmailQueue
WHERE DateEmailKey IS NULL
)
IF #MailIdFound = 0
BEGIN SET #Exit = 1 END --exit here as
ELSE
BEGIN --send the mail here
DECLARE #DateEmailKey INT
DECLARE #EmailBCC NVARCHAR(1000)
DECLARE #EmailTO NVARCHAR(1000)
DECLARE #EmailCC NVARCHAR(1000)
DECLARE #EmailBody NVARCHAR(MAX)
DECLARE #EmailImportance VARCHAR(6)
DECLARE #EmailSubject NVARCHAR(1000);
WITH myMostUrgentMail_cte
AS
(
SELECT TOP 1
DateEmailKey,
EmailBCC,
EmailTO,
EmailCC,
EmailBody,
EmailImportance,
EmailSubject
FROM WH.dbo.EmailQueue
WHERE EmailId = #MailIdFound
)
SELECT #DateEmailKey = DateEmailKey,
#EmailTO = EmailTO,
#EmailCC = EmailCC,
#EmailBCC = EmailBCC,
#EmailBody = EmailBody,
#EmailSubject = EmailSubject
FROM myMostUrgentMail_cte;
SET #EmailBody = #EmailBody + '<html>
<span style=''font-size:11.0pt;font-family:"Calibri","sans-serif"; color:black''><p><b>blah blah</b></p></span></html>'
EXEC msdb..sp_send_dbmail
#recipients = #EmailTO,
#copy_recipients = #EmailCC,
#blind_copy_recipients = #EmailBCC,
#subject = #EmailSubject,
#Importance = #EmailImportance,
#body_format = 'html',
#body = #EmailBody
UPDATE x
SET x.DateEmailKey = (CONVERT(CHAR(8),GETDATE(),(112))),
x.DateEmailTime = (CONVERT([time](7),left(CONVERT([char](12),GETDATE(),(114)),(8)),(0)))
FROM WH.dbo.EmailQueue x
WHERE x.EmailId = #MailIdFound
END
END
END TRY
BEGIN CATCH
-- handle error here
EXEC msdb..sp_send_dbmail
#recipients = 'ME#ME.com;'
, #subject = 'ERROR OCCURED DURING EMAIL CREATION'
, #body_format = 'html'
, #body = 'ERROR OCCURED'
UPDATE x
SET x.ErrorOccured = 1
FROM WH.dbo.EmailQueue x
WHERE x.EmailId = #MailIdFound
END CATCH;
Why do I still receiving in the emails: Warning: Null value is eliminated by an aggregate or other SET operation. If I have set the ansi_warnings off
set ansi_warnings off
set #subj = 'xxx'
set #msg = 'xxx' + char(13) + char(10)
set #q = 'select LSRNbr, trh.ShipperId, InvoiceNbr, Qty, count(LotSerNbr) as QtyRcvd
from tblRIM2_Header trh (nolock)
left outer join tblRIM2_SerialsFromFile trs (nolock) on trh.ShipperId = trs.ShipperId
where isnull(Completed,0) = 0
group by trh.ShipperId, LSRNbr, InvoiceNbr, Qty'
exec master.dbo.xp_sendmail
#recipients = 'xxx',
#subject = #subj ,
#query = #q,
#message = #msg,
#attach_results = FALSE,
#dbuse = 'GlobalQCS'
set ansi_warnings on
You have to put set ansi_warnings off inside #q:
set #q = 'set ansi_warnings off select LSRNbr, trh.ShipperId, ...`