MERGE SQL code not working correctly - sql

I was wondering if anyone could help.
I have this piece of code in my stored procedure, but the Merge is not working for field Address. Works for the other fields.
I have a source file with all address to be filled to the Source.
The Source contains a field with all addresses. When I run the query the Target Address column fills only one row with the correct address. I can see that there was a Location change in source, the Location with the Address was updated for that one row, but not for the rest of the properties in the table.
DECLARE #SQLMerge nvarchar(4000)
SET #SQLMerge=' MERGE '+#RPTblName+' AS target'+
' USING '+#CMTblName+' AS source
ON target.VersionEndDate IS NULL AND target.PtyId = source.PtyId
WHEN MATCHED AND NOT (target.Location =source.Location AND target.Price=source.Price
AND target.PtyCode=source.PtyCode
AND target.[FloorSpace] = source.[FloorSpace]
AND target.Address = source.Address)
THEN UPDATE SET VersionEndDate ='''+CONVERT(NVARCHAR(50),#ReportMonthEND,121 )+''';'
IF #debug=1 print #SQLMerge
EXECUTE sp_executesql #SQLMerge

Try this:
DECLARE #SQLMerge nvarchar(4000)
SET #SQLMerge=' MERGE '+#RPTblName+' AS target'+
' USING '+#CMTblName+' AS source
ON target.VersionEndDate IS NULL AND target.PtyId=source.PtyId
WHEN MATCHED AND NOT (target.Location =source.Location AND target.Price=source.Price
AND target.PtyCode=source.PtyCode
AND target.[FloorSpace] = source.[FloorSpace]
AND target.Address = source.Address)
THEN UPDATE SET target.VersionEndDate ='''+CONVERT(NVARCHAR(50),#ReportMonthEND,121 )+''';'
IF #debug=1 print #SQLMerge
EXECUTE sp_executesql #SQLMerge

Related

How can I write this SQL while loop code to get an XML results in one line instead of 3 separate lines?

I'm trying to get all this XML result in one line instead of 3 for each column
DECLARE #ii INT = 10;
DECLARE #String1 NVARCHAR(4000);
SET #String1 = '';
WHILE(#ii <= 18)
BEGIN
SET #String1 = (#String1 + 'SELECT LoanNumber = ''Complaint'+CONVERT(VARCHAR(2),#ii)+'-Call1'' , LoanStatus=''Compliants'' , LoanStatusDate = CAST(GETDATE() AS DATE)
UNION
SELECT LoanNumber = ''Complaint'+CONVERT(VARCHAR(2),#ii)+'-Call2'', LoanStatus=''Compliants'' , LoanStatusDate = CAST(GETDATE() AS DATE)
UNION
SELECT LoanNumber = ''Complaint'+CONVERT(VARCHAR(2),#ii)+'-Call3'', LoanStatus=''Compliants'' , LoanStatusDate = CAST(GETDATE() AS DATE)')
IF #ii != 18
SET #string1 = #string1 + ' UNION '
ELSE
SET #string1 = #string1 + 'FOR XML PATH (''Loan''),ROOT(''Loans'') '
SET #ii = #ii+1
END
EXEC sp_executesql #String1
I want something like this:
<Loans>
<LoanNumber>Complaint10-Call1<LoanStatus>Compliants<LoanStatusDate>2019-01-18
</Loan>
<Loan>
<LoanNumber>Complaint10-Call2 <LoanStatus>Compliants<LoanStatusDate>2019-01-18
</Loan>
<Loan>
<LoanNumber>Complaint10-Call3<LoanStatus>Compliants<LoanStatusDate>2019-01-18
</Loan>
Instead of the result that you get when you execute the code I provided. I appreciate your help.
This might be wild guessing, but I've got the feeling, that I understand, what this is about:
if you run the code you will see the result. no input data is needed .
I just want the structure of the xml outcome to all be on one line for
one set of each loop
Your provided code leads to this:
<Loans>
<Loan>
<LoanNumber>Complaint10-Call1</LoanNumber>
<LoanStatus>Compliants</LoanStatus>
<LoanStatusDate>2019-01-22</LoanStatusDate>
</Loan>
<Loan>
<LoanNumber>Complaint10-Call2</LoanNumber>
<LoanStatus>Compliants</LoanStatus>
<LoanStatusDate>2019-01-22</LoanStatusDate>
</Loan>
<!-- more of them-->
</Loans>
This is perfectly okay, valid XML.
But you want the result
outcome to all be on one line for one set of each loop
Something like this?
<Loans>
<Loan>
<LoanNumber>Complaint10-Call1</LoanNumber><LoanStatus>Compliants</LoanStatus><LoanStatusDate>2019-01-22</LoanStatusDate>
</Loan>
<!-- more of them-->
</Loans>
There is a big misconception I think... XML is not the thing you see. The same XML can look quite differently, without any semantic difference:
Check this out:
DECLARE #xmltable table(SomeXml XML)
INSERT INTO #xmltable VALUES
--the whole in one line
('<root><a>test</a><a>test2</a></root>')
--all <a>s in one line
,('<root>
<a>test</a><a>test2</a>
</root>')
--each element in one line
,('<root>
<a>test</a>
<a>test2</a>
</root>')
--white space going wild...
,('<root>
<a>test</a>
<a>test2</a>
</root>');
--now check the results
SELECT * FROM #xmltable;
This means: How the XML appears is a matter of the interpreter. The same XML opened with another tool might appear differently. Dealing with XML means dealing with data but not with format... The actual format has no meaning and should not matter at all...
Starting with SQL-Server 2016 you might have a look at JSON, if you need a tiny format:
DECLARE #somedata table(SomeValue VARCHAR(100),SomeStatus VARCHAR(100),SomeDate DATE);
INSERT INTO #somedata VALUES
('Complaint10-Call1','Complaints','2019-01-22')
,('Complaint10-Call2','Complaints','2019-01-22')
,('Complaint10-Call3','Complaints','2019-01-22');
SELECT * FROM #somedata FOR JSON PATH;
The result comes in one line:
[{"SomeValue":"Complaint10-Call1","SomeStatus":"Complaints","SomeDate":"2019-01-22"},{"SomeValue":"Complaint10-Call2","SomeStatus":"Complaints","SomeDate":"2019-01-22"},{"SomeValue":"Complaint10-Call3","SomeStatus":"Complaints","SomeDate":"2019-01-22"}]

SQL HTML email showing blank when one table has no results

The following code sends 2 diferent tables based on an sql query through the function sp_send_dbmail , the catch is , if both tables return results , the email shows up without any problem , perfectly. If one of the tables has NO results, the email comes up completly blank.
How can i fix this?
Thanks
declare #tableHTML NVARCHAR(MAX);
set #tableHTML = N'Este foi o resultado de Faturas Emitidas: <br><br><table border ="1">' +
N'<tr><th>Documento</th></tr>' +
cast (( select td = cc.tx
from cc
for xml path ('tr'),type) as nvarchar(max)) +
N' </table><table border ="1"><tr><th>Valor Total Vencido</th></tr>'
+
cast (( select td = fx.tc
from fx
for xml path ('tr'),type) as nvarchar(max)) +
N'</table>';
EXEC sp_send_dbmail
#profile_name ='xx_SqlMail',
#recipients ='ccccc#hotmail.com',
#subject ='Resumo',
#body =#tableHTML,
#body_format='HTML';
I would suspect that part of your query is returning a NULL value. Concatenating any value with a NULL will always result in NULL.
SELECT 'A' + NULL + 'B' will return NULL.
As you are doing multiple concatenations it would mean that if any value is NULL then #tableHTML will be NULL. Try wrapping your selects in an ISNULL().
select ISNULL(td, '') = cc.tx ...
Any table in your concatenation that returns a NULL will make the entire concatenation NULL.
To resolve this, just wrap each section that could potentially be NULL with an ISNULL().
I had a similar issue where I was running two separate queries and building two tables that I wanted to include in the body of the email. One would occasionally return no values and the email would come back blank. Using ISNULL fixed it for me.
See the code below for an example of what I did:
set #tablesHTML = **ISNULL**(#tableOneHTML,'NO RESULTS')
+ **ISNULL**(#tableTwoHTML,'NO RESULTS')
exec XXXXXX.[XXX].[sp_send_dbmail]
#profile_name='Mail'
,#recipients = #EmailRecipients
,#copy_recipients= #EmailCopyRecipients
,#subject = 'Email Subject Here'
,#body = #tablesHTML
,#body_format = 'HTML'

Can Multiple Parameter be used with LIKE in SQL

I am getting data from database in a format like "chem*,bio*" what i want to do is after i split the string into two i want to fetch all records containing "chem" and "bio" .. using LIKE with multiple parameter is something i want since CONTAIN will bring in irrelevant data too. Kindly help.
its something like this
assume:
#cwork2 ='chem*,bio*'
#cw1=#cw1 +'OR contains (name,'''+#Cwork1+''')'
#cw1=#cw1 +'OR name LIKE ('''+#Cwork1+''','%')'
Try this:
You can use pipeline (|) to achieve Or Condition
select * from Tablename where name like '[chem|bio]%';
just add them in an OR condition.
#cw1 = #cw1 OR name like '%chem%' OR name like '%bio%'
i found another way... although he answers provided are right on track but when talking about variables we cannot simply add on variables in the code. Hence forth i decided to put the variable in a #temp table, loop it through and then accordingly fetch data
insert into #publication select item from fsplit(#Work,',')
Declare #loopc int=1
while (#loopc <= (SELECT count(*) from #pub))
Begin
set #Cwork1= (select name from #pub where id= #loopc);
if CHARINDEX(#Cwork1,'*')<0
Begin
set #cw1='or pub.name ='''+#Cwork1+''')'
end
else
begin
set #Cwork1 = REPLACE(#Cwork1,'*','%');
set #cw1=#cw1 +'OR pub.name LIKE ('''+#Cwork1+''')'
end
set #loopc= #loopc +1;
end
set #cw1= (SELECT STUFF(#cw1, CHARINDEX('or', #cw1), LEN('or'), ''))
set #cw1= '('+#cw1+')'
set #Au2= #Au2 + ' and '+ #cw1

Update(Replace partcial value) XML Column in SQL

I have an XML column in my Table and i wanted to replace particular text wherever it appear in that column with a new text. Here is the xml structure,
<Story>
<StoryNonText>
<NonText>
<ImageID>1</ImageID>
<Src>http://staging.xyz.com/FolderName/1.png</Src>
</NonText>
<NonText>
<ImageID>2</ImageID>
<Src>http://staging.xyz.com/FolderName/2.png</Src>
</NonText>
</StoryNonText>
</Story>
In the above XML I wanted to replace all the <Src> values having http://staging.xyz.com/ to http://production.xyz.com/. Please guide me how i can do this!
You can use Replace() function as below:
Update TableName
SET
ColumnName=replace(CAST(ColumnName AS VARCHAR(8000)),'<Src>http://staging.xyz.com/','<Src>http://production.xyz.com/')
With a little help from a couple of XML functions you can do this in a loop.
The loop is necessary since replace value of can only replace one value at a time. This code assumes the URL is located first in the node and not embedded in text anywhere.
declare #T table(X xml);
insert into #T(X) values('<Story>
<StoryNonText>
<NonText>
<ImageID>1</ImageID>
<Src>http://staging.xyz.com/FolderName/1.png</Src>
</NonText>
<NonText>
<ImageID>2</ImageID>
<Src>http://staging.xyz.com/FolderName/2.png</Src>
</NonText>
</StoryNonText>
</Story> ');
declare #FromURL nvarchar(100);
declare #ToURL nvarchar(100);
set #FromURL = 'http://staging.xyz.com/';
set #ToURL = 'http://production.xyz.com/';
while 1 = 1
begin
update #T
set X.modify('replace value of (//*/text()[contains(., sql:variable("#FromURL"))])[1]
with concat(sql:variable("#ToURL"), substring((//*/text()[contains(., sql:variable("#FromURL"))])[1], string-length(sql:variable("#FromURL"))+1))')
where X.exist('//*/text()[contains(., sql:variable("#FromURL"))]') = 1;
if ##rowcount = 0
break;
end;
select *
from #T
replace value of (XML DML)
concat Function (XQuery)
contains Function (XQuery)
string-length Function (XQuery)
sql:variable() Function (XQuery)
There are many ways to do that.
The first way is to add a WHILE loop. Inside a loop, you search (CHARINDEX) for a position of first tag and first tag. Then, knowing the start and end positions, replace the value. Then on the next iteration you search again, but change starting position in CHARINDEX() function
The second way is to use SELECT ... FROM OPENXML + EXEC sp_xml_preparedocument

In this stored procedure I'm getting error converting datatype varchar to datetime

Pls Help in this while I am executing this stored procedure I'm getting error
Error Converting datatype varchar to datetime
in the database that created as date only.
Columns contains date datatype
Lawcurdatefrm, Lawcurdateto
Lawcomdatefrom,Lawcomdateto
These four columns are of date datatypes
My requirement is I need a records FromDate to ToDate
Example
For current year I'm passing in those dates
Lawcurdatefrm = 01/04/2011
Lawcurdateto = 31/03/2012
For comparison of date I'm using
Lawcomdatefrom = 01/04/2010
Lawcomdateto = 31/03/2011
After applying this condition that should show records for current year and previous year. If no records found in the previous year that should display zero.
CREATE PROCEDURE MVR_New_L_New_La_RPRT_spO
#language Ctxt_Language,
#operationname Ctxt_Operation,
#ouinstance Ctxt_OuInstance,
#user Ctxt_User,
#Brndnamefrm Brndnamefrm,
#Brndnameto Brndnameto,
#Frgtypefrm Frgtypefrm,
#Frgtypeto Frgtypeto,
#LAWAND_SAL_ANANAME1 LAWAND_SAL_ANANAME1,
#LAWAND_SAL_PRINT LAWAND_SAL_PRINT,
#LAWAND_SAL_RENDERTYPE1 LAWAND_SAL_RENDERTYPE1,
#LAWAND_SAL_RPTID1 LAWAND_SAL_RPTID1,
#LAWAND_SAL_RPTYPE1 LAWAND_SAL_RPTYPE1,
#LAWAND_SAL_subaction LAWAND_SAL_subaction,
#Lawcomdatefrom Lawcomdatefrom,
#Lawcomdateto Lawcomdateto,
#Lawcurdatefrm Lawcurdatefrm,
#Lawcurdateto Lawcurdateto,
#LawCustCodefrm LawCustCodefrm,
#LawCustCodeto LawCustCodeto,
#LawDocnofrm LawDocnofrm,
#LawDocnoto LawDocnoto,
#Lawitemfrm Lawitemfrm,
#Lawitemto Lawitemto,
#lawprintcombo lawprintcombo,
#m_errorid m_errorid OUT
AS
Begin
--nocount should be switched on to prevent phantom rows
Set nocount on
--#m_errorid should be 0 to Indicate Success
Set #m_errorid=0
--declaration of local variables
--temporary and formal parameters mapping
SET #language = ltrim(rtrim(#language))
SET #operationname = ltrim(rtrim(#operationname))
SET #ouinstance = ltrim(rtrim(#ouinstance))
SET #user = ltrim(rtrim(#user))
SET #Brndnamefrm = ltrim(rtrim(#Brndnamefrm))
SET #Brndnameto = ltrim(rtrim(#Brndnameto))
SET #Frgtypefrm = ltrim(rtrim(#Frgtypefrm))
SET #Frgtypeto = ltrim(rtrim(#Frgtypeto))
SET #LAWAND_SAL_ANANAME1=ltrim(rtrim(#LAWAND_SAL_ANANAME1))
SET #LAWAND_SAL_PRINT=ltrim(rtrim(#LAWAND_SAL_PRINT))
SET #LAWAND_SAL_RENDERTYPE1=ltrim(rtrim(#LAWAND_SAL_RENDERTYPE1))
SET #LAWAND_SAL_RPTID1=ltrim(rtrim(#LAWAND_SAL_RPTID1))
SET #LAWAND_SAL_RPTYPE1=ltrim(rtrim(#LAWAND_SAL_RPTYPE1))
SET #LAWAND_SAL_subaction=ltrim(rtrim(#LAWAND_SAL_subaction))
SET #Lawcomdatefrom=ltrim(rtrim(#Lawcomdatefrom))
SET #Lawcomdateto=ltrim(rtrim(#Lawcomdateto))
SET #Lawcurdatefrm=ltrim(rtrim(#Lawcurdatefrm))
SET #Lawcurdateto=ltrim(rtrim(#Lawcurdateto))
SET #LawCustCodefrm=ltrim(rtrim(#LawCustCodefrm))
SET #LawCustCodeto=ltrim(rtrim(#LawCustCodeto))
SET #LawDocnofrm=ltrim(rtrim(#LawDocnofrm))
SET #LawDocnoto=ltrim(rtrim(#LawDocnoto))
SET #Lawitemfrm=ltrim(rtrim(#Lawitemfrm))
SET #Lawitemto=ltrim(rtrim(#Lawitemto))
SET #lawprintcombo=ltrim(rtrim(#lawprintcombo))
If #Lawcurdatefrm='' or isnull(#Lawcurdatefrm,'')=''
begin
raiserror('Please enter a valid Current From Date',16,1)
return
end
If #Lawcurdateto='' or isnull(#Lawcurdateto,'')=''
begin
raiserror('Please enter a valid Current to Date',16,1)
return
end
--select 'albus',#Lawcomdatefrom,#Lawcomdateto,#Lawcurdatefrm,#Lawcurdateto
(SELECT isnull (Itemqty1,0) from law_sale_view where custordinv_hdr_tran_date between #Lawcomdatefrom and #Lawcomdateto )
(SELECT isnull(itemvalue1,0) from law_sale_view where custordinv_hdr_tran_date between #Lawcurdatefrm and #Lawcurdateto)
Select 0 'Lw_BrndNm',
convert(varchar(10),custordinv_hdr_anchor_date,109) 'Lw_Comfrmdate',
itemqty1 'Lw_ComQt',
convert(varchar(10),custordinv_hdr_anchor_date,109) 'Lw_Comtodate',
itemvalue1 'Lw_ComVal',
convert(varchar(10),custordinv_hdr_tran_date,109) 'Lw_Curfrmdate',
custordinv_dtl_item_qty'Lw_CurQt',
convert(varchar(10),custordinv_hdr_tran_date,109) 'Lw_Curtodate',
custordinv_dtl_item_amt 'Lw_Curval',
custlo_cust_code 'Lw_CustCod',
custlo_cust_name 'Lw_CustNam',
stdattrvalue1 'Lw_Frghttyp',
custordinv_dtl_item_tcd_code 'Lw_ItmCod',
itemdesc 'Lw_ItmDes',
custordinv_dtl_uom 'Lw_UOM'
from law_sale_view
--where custlo_cust_code=custlo_cust_code
Set nocount off
End
Please remove
convert(varchar(10),custordinv_hdr_anchor_date,109)
in all datetime place & try...
Rewrite the date value to something like yyyy/MM/dd format, for example your "31/03/2011" to "2011/03/31". Why? when your transform string "31/03/2011" to date the 31 will be assumed to be month instead of day.