SQL Cursor Problem CODE 16915 Cursor name already exists - sql

I have a problem with a cursor inside SQL Server stored procedure.
Here is the code:
if (#pEvento = 84)
begin
set #pAsun_mail = #pAsun_mail + ' FUP ' + CONVERT(varchar(10), #pFupID) + ' ' + #pVersion;
DECLARE #ConsecutivoTemp int, #FechaTemp date, #ValorTemp money, #CondicionTemp varchar(50), #GeneraBoletoTemp bit;
DECLARE CondicionPago_Cursor CURSOR FOR
SELECT fccp_Consecutivo, Fecha, Valor, Condicion, fccp_BoletosBancarios FROM [dbo].[fup_CuotasCondicionesPago]
WHERE fccp_entrada_cot_id = (SELECT [eect_id]
FROM fup_enc_entrada_cotizacion
WHERE [eect_fup_id] = #pFupID
AND [eect_vercot_id] = #pVersion) AND fccp_TipoPago_id = 3;
OPEN CondicionPago_Cursor;
FETCH NEXT FROM CondicionPago_Cursor INTO
#ConsecutivoTemp, #FechaTemp, #ValorTemp, #CondicionTemp, #GeneraBoletoTemp;
DECLARE #HTMLTableLeasing varchar(max);
WHILE ##FETCH_STATUS = 0
BEGIN
SET #HTMLTableLeasing = #HTMLTableLeasing + '<tr>';
SET #HTMLTableLeasing = #HTMLTableLeasing + '<td>'+ CONVERT(varchar(3), #ConsecutivoTemp) +'</td>';
SET #HTMLTableLeasing = #HTMLTableLeasing + '<td>'+ CONVERT(varchar(20), #FechaTemp) +'</td>';
SET #HTMLTableLeasing = #HTMLTableLeasing + '<td>'+ CONVERT(varchar(15), #ValorTemp) +'</td>';
SET #HTMLTableLeasing = #HTMLTableLeasing + '<td>'+ #CondicionTemp +'</td>';
IF #GeneraBoletoTemp = 1
BEGIN
SET #HTMLTableLeasing = #HTMLTableLeasing + '<td><input type="checkbox" disabled checked /></td>';
END
ELSE
BEGIN
SET #HTMLTableLeasing = #HTMLTableLeasing + '<td><input type="checkbox" disabled/></td>';
END
SET #HTMLTableLeasing = #HTMLTableLeasing + '</tr>';
FETCH NEXT FROM CondicionPago_Cursor INTO
#ConsecutivoTemp, #FechaTemp, #ValorTemp, #CondicionTemp, #GeneraBoletoTemp;
END
CLOSE CondicionPago_Cursor
DEALLOCATE CondicionPago_Cursor
set #pMsg = #pMsg + #HTMLTableLeasing
end
And the error says:
Already exists a cursor with name 'CondicionPago_Cursor'
I tried checking again the order or STATEMENTS OPEN, FETCH, CLOSE, DEALLOCATE but I think they have a correct order.
I'm tryin to iterate over a set or records to create dynamically a body of a table, you can see the tags <th> and <td>.

As #Lamu already mentioned, there are better ways to compose (X)HTML.
Also, there is no need to concatenate strings like in the #JohnInk answer.
Here is a conceptual example for you, including CSS for styling.
It will work starting from SQL Server 2005 onwards.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (
ID INT IDENTITY PRIMARY KEY
, state CHAR(2)
, city VARCHAR(30)
);
INSERT INTO #tbl (state, city)
VALUES
('FL', 'Miami')
, ('CA', 'Los Angeles')
, ('TX', 'Austin');
-- DDL and sample data population, end
DECLARE #xhtmlBody XML
, #body NVARCHAR(MAX)
, #tableCaption VARCHAR(30) = 'US states and cities';
SET #xhtmlBody = (SELECT (
SELECT * FROM #tbl FOR XML PATH('row'), TYPE, ROOT('root'))
.query('<html><head>
<meta charset="utf-8"/>
(: including embedded CSS styling :)
<style>
table <![CDATA[ {border-collapse: collapse; width: 300px;} ]]>
th <![CDATA[ {background-color: #4CAF50; color: white;} ]]>
th, td <![CDATA[ { text-align: left; padding: 8px;} ]]>
tr:nth-child(even) <![CDATA[ {background-color: #f2f2f2;} ]]>
td:nth-child(3) <![CDATA[ {background-color: red;} ]]>
#green <![CDATA[ {background-color: lightgreen;} ]]>
</style>
</head>
<body>
<table border="1">
<caption><h2>{sql:variable("#tableCaption")}</h2></caption>
<thead>
<tr>
<th>No.</th>
<th>State</th>
<th>City</th>
</tr>
</thead>
<tbody>
{
for $row in /root/row
return <tr>
<td>{data($row/ID)}</td>
<td>{data($row/state)}</td>
<td>
{if ($row/city/text()="Los Angeles") then attribute id {"green"} else ()}
{data($row/city)}
</td>
</tr>
}
</tbody></table></body></html>'));
SELECT #xhtmlBody;
Output
Saved as a file, and tested in any Internet browser

First: the error comes from using the global cursor. So, every time you run this it will run into itself. Add a LOCAL keyword.
DECLARE CondicionPago_Cursor CURSOR LOCAL FOR
But, you want to avoid cursor loops whenever possible. They are much less efficient. You might do something like instead.
SELECT #HTMLTableLeasing = #HTMLTableLeasing + '<tr><td>' + CAST(fccp_Consecutivo
AS varchar(3)) + '</td><td>' +
CAST(Fecha AS varchar(20)) + '</td><td>' +
CAST(Valor AS varchar(15)) + '</td><td>' +
Condicion + '</td><td>' +
CASE WHEN GeneraBoleto = 1
THEN '<input type="checkbox" disabled checked />'
ELSE '<input type="checkbox" disabled/>' END +
'</td></tr>'
FROM [dbo].[fup_CuotasCondicionesPago]
WHERE fccp_entrada_cot_id = (SELECT [eect_id]
FROM fup_enc_entrada_cotizacion
WHERE [eect_fup_id] = #pFupID
AND [eect_vercot_id] = #pVersion) AND fccp_TipoPago_id = 3

Related

Using "for xml" to format SQL results that include results that are NULL?

I have an SQL query basically as follows:
DECLARE #BODY1 NVARCHAR(MAX)
SET #BODY1 = CAST((SELECT td = Name + '</td><td>' + Number + '</td><td>' + Address + '</td>'
FROM
(
SELECT
Name, Number, Address
FROM
Table1
) as Sub
FOR XML PATH('tr'), type) AS VARCHAR(MAX))
SET #BODY1 = '<TABLE CELLPADDING="3" CELLSPACING="3" BORDER="1">'+
'<TR><TH>Name</TH><TH>Number</TH><TH>Address</TH></TR> +
+ REPLACE(REPLACE(#Body1, '<','<'), '>','>') + '</TABLE>'
EXEC MSDB.DBO.SP_SEND_DBMAIL
#PROFILE_NAME = 'NAME',
#RECEPIENTS = 'NAME#DOMAIN.COM',
#BODY = #Body1,
#SUBJECT = 'Details',
#BODY_FORMAT = 'HTML',
#EXECUTE_QUERY_DATABASE = 'NAME';
The data I have can be summarised as follows:
NAME NUMBER ADDRESS
Bob 12345 1 Street, Town
John 23456
Scott 34567 3 Avenue, City
When I run this code which sends me an email containing the results of the query, I only get Bob and Scott's record. This example is simplified, but if there are any rows that do not have data in each field then they do not show in the email.
I've read somewhere that perhaps this is due to needing another variable as part of the XML code, but I can't quite put my finger on what it is. Please can someone assist me?
Thanks in advance.
Your primary issue is that + will return null if any of the values are null. So you could use either ISNULL or CONCAT
But this is in any case not the correct way to create XML. You should just unpivot the values and use FOR XML properly.
DECLARE #BODY1 NVARCHAR(MAX) =
(
SELECT
ISNULL(v.td, '') AS td
FROM
Table1
CROSS APPLY (VALUES
(Name),
(Number),
(Address)
) v(td)
FOR XML PATH('tr')
);
You need to be able to prepare for the entire output of this expression to be NULL:
SET #BODY1 = CAST((SELECT td = Name + '</td><td>'
+ Number + '</td><td>'
+ Address + '</td>' ...
A couple of ways to handle that. You can use COALESCE to convert NULL to empty string:
SET #BODY1 = CAST((SELECT td = COALESCE(Name, '') + '</td><td>'
+ COALESCE(Number, '') + '</td><td>'
+ COALESCE(Address, '') + '</td>' ...
Or CONCAT(), which does that for you:
SET #BODY1 = CAST((SELECT td = CONCAT
(Name, '</td><td>', Number, '</td><td>', Address, '</td>') ...
There are also certainly other approaches to your entire problem space that are a lot less messy, but this is at least a start to get your missing row back.
For example, on SQL Server 2017, you can use STRING_AGG() and CONCAT_WS():
SELECT #BODY1 = '<table ...>
<TR><TH>Name</TH><TH>Number</TH><TH>Address</TH></TR><tr>'
+ STRING_AGG('<td>'+CONCAT_WS('</td><td>',Name,Number,Address)
+'</td>','</tr><tr>') + '</tr></table>'
FROM dbo.Table1;
This is also, admittedly, ugly. Another way:
SELECT #BODY1 = '<table ...>
<TR><TH>Name</TH><TH>Number</TH><TH>Address</TH></TR>
<tr>' + td + '</table>'
FROM
(
SELECT td FROM
(
SELECT Name = COALESCE(Name, ''),
Number = COALESCE(Number,''),
Address = COALESCE(Address,'')
FROM dbo.Table1
) AS cp UNPIVOT(td FOR cols IN (Name, Number, Address)) AS up
FOR XML PATH('tr')
) AS x(td);
Please try the following XQuery based approach that gererates XHTML for the email.
Notable points:
No strings concatenation.
No worries for NULL values.
Very easy to create, very easy to maintain.
UI styling is controlled via CSS.
SQL
DECLARE #tbl TABLE (ID INT IDENTITY PRIMARY KEY, [Name] VARCHAR(20), Number CHAR(5), [Address] VARCHAR(100));
INSERT INTO #tbl (Name, Number, Address) VALUES
('Bob ', '12345' ,'1 Street, Town'),
('John ', '23456' , NULL),
('Scott', '34567' ,'3 Avenue, City');
DECLARE #xhtmlBody XML
, #body NVARCHAR(MAX)
, #tableCaption VARCHAR(30) = 'Customers list';
SET #xhtmlBody = (SELECT (
SELECT * FROM #tbl FOR XML PATH('row'), TYPE, ROOT('root'))
.query('<html><head>
<meta charset="utf-8"/>
(: including embedded CSS styling :)
<style>
table <![CDATA[ {border-collapse: collapse; width: 300px;} ]]>
th <![CDATA[ {background-color: #4CAF50; color: white;} ]]>
th, td <![CDATA[ { text-align: left; padding: 8px;} ]]>
tr:nth-child(even) <![CDATA[ {background-color: #f2f2f2;} ]]>
#green <![CDATA[ {background-color: lightgreen;} ]]>
</style>
</head>
<body>
<table border="1">
<caption><h2>{sql:variable("#tableCaption")}</h2></caption>
<thead>
<tr>
<th>No.</th>
<th>Name</th>
<th>Number</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{
for $row in /root/row
return <tr>
<td>{data($row/ID)}</td>
<td>{data($row/Name)}</td>
<td>{data($row/Number)}</td>
<td>{data($row/Address)}</td>
</tr>
}
</tbody></table></body></html>'));
SELECT #xhtmlBody;
SET #body = CAST(#xhtmlBody AS NVARCHAR(MAX));
Output

How to correct the scalar variable declaration error in my SQL job?

I am using SQL Server 2012 and I have the following stored procedure which is returning the required output in the form of a HTML table:
CREATE PROCEDURE dbo.ITB_SendEmail
AS
BEGIN
DECLARE #Body NVARCHAR(MAX),
#Body2 NVARCHAR(MAX),
#TableHead VARCHAR(1000),
#TableTail VARCHAR(1000)
SET #TableTail = '</table></body></html>' ;
SET #TableHead = '<html><head>' + '<style>'
+ 'td {border: solid black;border-width: 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font: 11px arial} '
+ '</style>' + '</head>' + '<body>' + 'Report generated on : '
+ CONVERT(VARCHAR(50), GETDATE(), 106)
+ ' <br> <table cellpadding=0 cellspacing=0 border=0>'
+ '<tr> <td bgcolor=#E6E6FA><b>StayYear</b></td>'
+ '<td bgcolor=#E6E6FA><b>Market</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jan</b></td>'
+ '<td bgcolor=#E6E6FA><b>Feb</b></td>'
+ '<td bgcolor=#E6E6FA><b>Mar</b></td>'
+ '<td bgcolor=#E6E6FA><b>Apr</b></td>'
+ '<td bgcolor=#E6E6FA><b>May</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jun</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jul</b></td>'
+ '<td bgcolor=#E6E6FA><b>Aug</b></td>'
+ '<td bgcolor=#E6E6FA><b>Sep</b></td>'
+ '<td bgcolor=#E6E6FA><b>Oct</b></td>'
+ '<td bgcolor=#E6E6FA><b>Nov</b></td>'
+ '<td bgcolor=#E6E6FA><b>Dec</b></td>';
SET #Body = ( SELECT td = StayYear, '',
td = Market, '',
td = Jan, '',
td = Feb, '',
td = Mar, '',
td = Apr, '',
td = May, '',
td = Jun, '',
td = Jul, '',
td = Aug, '',
td = Sep, '',
td = Oct, '',
td = Nov, '',
td = Dec, ''
FROM View1
FOR XML RAW('tr'),
ELEMENTS
)
SET #Body2 = #TableHead + ISNULL(#Body, '') + #TableTail
SELECT #Body2
END
I have now set up a SQL job which is supposed to execute this stored procedure and emails the output to a recipient. My SQL Server job runs a T-SQL query (see below):
DECLARE #GeneratedHTML NVARCHAR(MAX);
EXEC ITB_SendEmail #GeneratedHTML = #Body2 OUTPUT
EXEC sp_send_dbmail
#profile_name='BI',
#copy_recipients ='',
#recipients='xxx#yyyy.com',
#subject='ITB',
#body= #GeneratedHTML ,
#body_format = 'HTML' ;
However, the SQL Server job is failing with the following an error message:
Must declare the scalar variable #Body2. [SQLSTATE 42000] (Error 137). The step failed
I cannot figure out the scalar variable declaration issue. What am I doing wrong?
The error is not referring to the variable in your Stored Procedure code if that's what you're thinking.
It's saying you need to DECLARE #Body2 in your Execution Batch. However you have more problems than that. You are trying to access an output parameter of your stored procedure, but in your stored procedure you haven't got an output parameter.
Reading the documentation on Output parameters would be a good start.
Assuming you correctly set #Body2 as an output parameter in your stored procedure, then you simply need to reverse their order in the execution statement:
DECLARE #GeneratedHTML NVARCHAR(MAX);
EXEC ITB_SendEmail #Body2 = #GeneratedHTML OUTPUT
EXEC sp_send_dbmail
#profile_name='BI',
#copy_recipients ='',
#recipients='xxx#yyyy.com',
#subject='ITB',
#body= #GeneratedHTML ,
#body_format = 'HTML' ;

How to convert a T-SQL query into a Stored Procedure?

I am running SQL Server 2012 and I need to convert a T-SQL query into a Stored Procedure. My aim is to run a SQL job that will execute this Stored Procedure on a daily basis.
My T-SQL query stands as follows:
DECLARE #Body NVARCHAR(MAX),
#TableHead VARCHAR(1000),
#TableTail VARCHAR(1000)
SET #TableTail = '</table></body></html>' ;
SET #TableHead = '<html><head>' + '<style>'
+ 'td {border: solid black;border-width: 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font: 11px arial} '
+ '</style>' + '</head>' + '<body>' + 'Report generated on : '
+ CONVERT(VARCHAR(50), GETDATE(), 106)
+ ' <br> <table cellpadding=0 cellspacing=0 border=0>'
+ '<tr> <td bgcolor=#E6E6FA><b>StayYear</b></td>'
+ '<td bgcolor=#E6E6FA><b>Market</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jan</b></td>'
+ '<td bgcolor=#E6E6FA><b>Feb</b></td>'
+ '<td bgcolor=#E6E6FA><b>Mar</b></td>'
+ '<td bgcolor=#E6E6FA><b>Apr</b></td>'
+ '<td bgcolor=#E6E6FA><b>May</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jun</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jul</b></td>'
+ '<td bgcolor=#E6E6FA><b>Aug</b></td>'
+ '<td bgcolor=#E6E6FA><b>Sep</b></td>'
+ '<td bgcolor=#E6E6FA><b>Oct</b></td>'
+ '<td bgcolor=#E6E6FA><b>Nov</b></td>'
+ '<td bgcolor=#E6E6FA><b>Dec</b></td>';
SET #Body = ( SELECT *
FROM View1
FOR XML RAW('tr'),
ELEMENTS
)
SELECT #Body = #TableHead + ISNULL(#Body, '') + #TableTail
What are the steps to convert the above into a Stored Procedure?
You Can add make your script as a Stored Procedure by simply binding your Query inside a Create Procedure statement. Like this
CREATE PROCEDURE <Database Schema>.<Procedue Name>
AS
BEGIN
<Your Script>
END
you can copy and paste your Query between the BEGIN and END.
Like this
CREATE PROCEDURE dbo.sProc_MyProc
AS
BEGIN
DECLARE #Body NVARCHAR(MAX),
#TableHead VARCHAR(1000),
#TableTail VARCHAR(1000)
SET #TableTail = '</table></body></html>' ;
SET #TableHead = '<html><head>' + '<style>'
+ 'td {border: solid black;border-width: 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font: 11px arial} '
+ '</style>' + '</head>' + '<body>' + 'Report generated on : '
+ CONVERT(VARCHAR(50), GETDATE(), 106)
+ ' <br> <table cellpadding=0 cellspacing=0 border=0>'
+ '<tr> <td bgcolor=#E6E6FA><b>StayYear</b></td>'
+ '<td bgcolor=#E6E6FA><b>Market</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jan</b></td>'
+ '<td bgcolor=#E6E6FA><b>Feb</b></td>'
+ '<td bgcolor=#E6E6FA><b>Mar</b></td>'
+ '<td bgcolor=#E6E6FA><b>Apr</b></td>'
+ '<td bgcolor=#E6E6FA><b>May</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jun</b></td>'
+ '<td bgcolor=#E6E6FA><b>Jul</b></td>'
+ '<td bgcolor=#E6E6FA><b>Aug</b></td>'
+ '<td bgcolor=#E6E6FA><b>Sep</b></td>'
+ '<td bgcolor=#E6E6FA><b>Oct</b></td>'
+ '<td bgcolor=#E6E6FA><b>Nov</b></td>'
+ '<td bgcolor=#E6E6FA><b>Dec</b></td>';
SET #Body = ( SELECT *
FROM View1
FOR XML RAW('tr'),
ELEMENTS
)
SELECT #Body = #TableHead + ISNULL(#Body, '') + #TableTail
END
Simply right-click 'Stored Procedures' and click 'Stored Procedure'.
A new window will open with some very basic code.
Delete the stuff in green
Name your Stored Procedure, with no spaces in the name of the SProc.
Paste your SQL script in between the BEGIN and END clauses.
Hit F5 to compile your Sproc.
If everything is setup correctly, you will get a message that reads
Command(s) completed successfully.

Delete script form xml document in SQL Server

I want to delete content from xml or txt document in SQL Server 2014 for this example:
<div class="infotagtitle">
<script type="text/javascript">
var sc_project=9934926;
var sc_invisible=1;
var sc_security="00dd8003";
var scJsHost = (("https:" == document.location.protocol) ?
"https://secure." : "http://www.");
document.write("<sc"+"ript type='text/javascript' src='" +
scJsHost+
"statcounter.com/counter/counter.js'></"+"script>");
</script>
</div>
Output:
<div class="infotagtitle">
</div>
The text code from the question is clearly HTML and not well-formed XML.
As such, the text can't be simply casted or converted to the XML type.
Which means XML type functions like f.e. SET #myXML.modify('delete //script'); aren't an option.
This example code uses a table variable to demonstrate updating a table with an NVARCHAR that contains HTML with script tags.
It uses PATINDEX to find the script code in the HTML.
An update is looped till no records remain with a script tag in the html.
declare #T table (Id int identity(1,1), html_text nvarchar(max));
insert into #T (html_text) values
(N'<html>
<body>
<div class="infotagtitle">
<script type="text/javascript">
var sc_project=9934926;
var sc_invisible=1;
var sc_security="00dd8003";
var scJsHost = (("https:" == document.location.protocol) ?
"https://secure." : "http://www.");
document.write("<sc"+"ript type=''text/javascript'' src=''" +
scJsHost+
"statcounter.com/counter/counter.js''></"+"script>");
</script>
</div>
<div class="othertagtitle">
<script type="text/javascript">
document.write("<script type=''text/javascript'' src=''" +
otherHost+
"othercounter.com/counter/counter.js''></"+"script>");
</script>
</div>
</body>
<html>');
declare #N INT, #Counter INT = 0;
select #N = count(*) from #T where patindex('%<script %',html_text) > 0;
while (#N > 0 AND #Counter < 10)
begin
set #Counter = #Counter + 1; -- just a safety measure to avoid an infinite loop
update #T
set html_text = concat(substring(html_text,1,patindex('%<script %',html_text)-1),substring(html_text,patindex('%</script>%',html_text)+9,len(html_text)))
where patindex('%<script %',html_text) > 0;
select #N = count(*) from #T where patindex('%<script %',html_text) > 0;
end;
select * from #T;

how to bypass the 65535 character limit in a select statement using "FOR XML"

I am aware of the 65535 truncation for text datatypes (and Varchar(MAX) as well). I am also aware of XML outputs that can be set to unlimited. I have a table that stores XML strings in a varchar(MAX) column called GEOM.
My problem is that the xml snippet held in the geom column can exceed 65535 characters. I figure since it's XML, and I'm creating an XML output in my code anyways, why not just build the xml and send that out as such, since I can set XML output to "Unlimited".
USE [buyerhero]
GO
/****** Object: StoredProcedure [dbo].[GEOIDKMLCOUNTY] Script Date: 9/17/2015 11:18:55 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GEOIDKMLCOUNTY] #CountyID nvarchar(30)
AS
DECLARE #kml XML
DECLARE #kmlout NVARCHAR(MAX)
SELECT #kml = CAST('<?xml version="1.0" encoding="utf-16" ?>' +
'<kml xmlns="http://www.opengis.net/kml/2.2">' +
'<Document>' +
' <Style id="Licensed">
<LineStyle>
<color>ff000000</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<color>1e1400FF</color>
<fill>1</fill>
<outline>1</outline>
</PolyStyle>
</Style>
<Style id="NotLicensed">
<LineStyle>
<color>ff000000</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<color>1e14F0FF</color>
<fill>1</fill>
<outline>1</outline>
</PolyStyle>
</Style>
<Style id="Other">
<LineStyle>
<color>ff000000</color>
<width>2</width>
</LineStyle>
<PolyStyle>
<color>1e007800</color>
<fill>1</fill>
<outline>1</outline>
</PolyStyle>
</Style>' +
(
select
'<![CDATA[{"County":"' + r.CountyName + ', ' + r.State + '", "GEOID": "'+t.GEOID+'"}]]>' as Name,
case t.IsLicensed
when 2 then '#Licensed'
when 1 then '#NotLicensed'
else '#Other'
end as StyleURL,
cast(replace(geom,'"','') as xml) as Geometry
from Tracts t
join census_county_ref c on t.GEOID = c.GEOID
join FIPSCountyCode r on c.STATEFP = r.StateANSI and c.COUNTYFP = r.CountyANSI
where r.CountyID = #CountyID
FOR XML PATH(''), ELEMENTS) + '</Document></kml>' AS XML)
--
-- Perform replacement of < and > with < and > respectively
--
SET #kmlout = REPLACE(REPLACE(CAST(#kml AS NVARCHAR(MAX)), '<', '<'), '>', '>')
SET #kmlout = REPLACE(#kmlout, 'utf-16', 'utf-8')
--
-- Return kmlout
--
SELECT #kmlout
in spite of the idea the geom columns is xml and I'm using cast(replace(geom,'"','') as xml) which is varchar(max), that field still gets truncated.
How do I "untruncate" the field so I can output the XML?
Thanks.
Use the concat function instead the + operator. the plus operator is limited to 8000 bytes.
SELECT #kml =CAST(concat('your xml', the select,'the other xml')