SQL Server: HTML Decode based on the HTML names in a String input - sql

I am trying to convert the HTML names like & " etc to their equivalent CHAR values using the SQL below. I was testing this in SQL Server 2012.
Test 1 (This works fine):
GO
DECLARE #inputString VARCHAR(MAX)= '&testString&'
DECLARE #codePos INT, #codeEncoded VARCHAR(7), #startIndex INT, #resultString varchar(max)
SET #resultString = LTRIM(RTRIM(#inputString))
SELECT #startIndex = PATINDEX('%&%', #resultString)
WHILE #startIndex > 0
BEGIN
SELECT #resultString = REPLACE(#resultString, '&', '&'), #startIndex=PATINDEX('%&%', #resultString)
END
PRINT #resultString
Go
Output:
&testString&
Test 2 (this isn't worked):
Since the above worked, I have tried to extend this to deal with more characters as following:
DECLARE #htmlNames TABLE (ID INT IDENTITY(1,1), asciiDecimal INT, htmlName varchar(50))
INSERT INTO #htmlNames
VALUES (34,'"'),(38,'&'),(60,'<'),(62,'>'),(160,' '),(161,'¡'),(162,'¢')
-- I would load the full list of HTML names into this TABLE varaible, but removed for testing purposes
DECLARE #inputString VARCHAR(MAX)= '&testString&'
DECLARE #count INT = 0
DECLARE #id INT = 1
DECLARE #charCode INT, #htmlName VARCHAR(30)
DECLARE #codePos INT, #codeEncoded VARCHAR(7), #startIndex INT
, #resultString varchar(max)
SELECT #count=COUNT(*) FROM #htmlNames
WHILE #id <=#count
BEGIN
SELECT #charCode = asciiDecimal, #htmlname = htmlName
FROM #htmlNames
WHERE ID = #id
SET #resultString = LTRIM(RTRIM(#inputString))
SELECT #startIndex = PATINDEX('%' + #htmlName + '%', #resultString)
While #startIndex > 0
BEGIN
--PRINT #resultString + '|' + #htmlName + '|' + NCHAR(#charCode)
SELECT #resultString = REPLACE(#resultString, #htmlName, NCHAR(#charCode))
SET #startIndex=PATINDEX('%' + #htmlName + '%', #resultString)
END
SET #id=#id + 1
END
PRINT #resultString
GO
Output:
&testString&
I cannot figure out where I'm going wrong? Any help would be much appreciated.
I am not interested to load the string values into application layer and then apply HTMLDecode and save back to the database.
EDIT:
This line SET #resultString = LTRIM(RTRIM(#inputString)) was inside the WHILE so I was overwriting the result with #inputString. Thank you, YanireRomero.
I like #RichardDeeming's solution too, but it didn't suit my needs in this case.

Here's a simpler solution that doesn't need a loop:
DECLARE #htmlNames TABLE
(
ID INT IDENTITY(1,1),
asciiDecimal INT,
htmlName varchar(50)
);
INSERT INTO #htmlNames
VALUES
(34,'"'),
(38,'&'),
(60,'<'),
(62,'>'),
(160,' '),
(161,'¡'),
(162,'¢')
;
DECLARE #inputString varchar(max)= '&test&quot;<String>"&';
DECLARE #resultString varchar(max) = #inputString;
-- Simple HTML-decode:
SELECT
#resultString = Replace(#resultString COLLATE Latin1_General_CS_AS, htmlName, NCHAR(asciiDecimal))
FROM
#htmlNames
;
SELECT #resultString;
-- Output: &test"<String>"&
-- Multiple HTML-decode:
SET #resultString = #inputString;
DECLARE #temp varchar(max) = '';
WHILE #resultString != #temp
BEGIN
SET #temp = #resultString;
SELECT
#resultString = Replace(#resultString COLLATE Latin1_General_CS_AS, htmlName, NCHAR(asciiDecimal))
FROM
#htmlNames
;
END;
SELECT #resultString;
-- Output: &test"<String>"&
EDIT: Changed to NCHAR, as suggested by #tomasofen, and added a case-sensitive collation to the REPLACE function, as suggested by #TechyGypo.

For the sake of performance, this isn't something you should do write as T-SQL statements, or as a SQL scalar value function. The .NET libraries provide excellent, fast, and, above all, reliable HTML decoding. In my opinion, you should implement this as a SQL CLR, like this:
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(
IsDeterministic = true,
IsPrecise = true,
DataAccess = DataAccessKind.None,
SystemDataAccess = SystemDataAccessKind.None)]
[return: SqlFacet(MaxSize = 4000)]
public static SqlString cfnHtmlDecode([SqlFacet(MaxSize = 4000)] SqlString input)
{
if (input.IsNull)
return null;
return System.Net.WebUtility.HtmlDecode(input.Value);
}
}
Then in your T-SQL, call it like this:
SELECT clr_schema.cfnHtmlDecode(column_name) FROM table_schema.table_name

Hey it was an assign error:
DECLARE #htmlNames TABLE (ID INT IDENTITY(1,1), asciiDecimal INT, htmlName varchar(50))
INSERT INTO #htmlNames
VALUES (34,'"'),(38,'&'),(60,'<'),(62,'>'),(160,' '),(161,'¡'),(162,'¢')
-- I would load the full list of HTML names into this TABLE varaible, but removed for testing purposes
DECLARE #inputString VARCHAR(MAX)= '&testString&'
DECLARE #count INT = 0
DECLARE #id INT = 1
DECLARE #charCode INT, #htmlName VARCHAR(30)
DECLARE #codePos INT, #codeEncoded VARCHAR(7), #startIndex INT
, #resultString varchar(max)
SELECT #count=COUNT(*) FROM #htmlNames
SET #resultString = LTRIM(RTRIM(#inputString))
WHILE #id <=#count
BEGIN
SELECT #charCode = asciiDecimal, #htmlname = htmlName
FROM #htmlNames
WHERE ID = #id
SELECT #startIndex = PATINDEX('%' + #htmlName + '%', #resultString)
While #startIndex > 0
BEGIN
--PRINT #resultString + '|' + #htmlName + '|' + NCHAR(#charCode)
SET #resultString = REPLACE(#resultString, #htmlName, NCHAR(#charCode))
SET #startIndex=PATINDEX('%' + #htmlName + '%', #resultString)
END
SET #id=#id + 1
END
PRINT #resultString
GO
this line SET #resultString = LTRIM(RTRIM(#inputString)) was inside the while so you were overwriting you result.
Hope it helps.

Some additional help for "Richard Deeming" response, to safe some typing for future visitors trying to upgrade the function with more codes:
INSERT INTO #htmlNames
VALUES
(34,'"'),
(38,'&'),
(60,'<'),
(62,'>'),
(160, ' '),
(161, '¡'),
(162, '¢'),
(163, '£'),
(164, '¤'),
(165, '¥'),
(166, '¦'),
(167, '§'),
(168, '¨'),
(169, '©'),
(170, 'ª'),
(171, '«'),
(172, '¬'),
(173, '­'),
(174, '®'),
(175, '¯'),
(176, '°'),
(177, '±'),
(178, '²'),
(179, '³'),
(180, '´'),
(181, 'µ'),
(182, '¶'),
(183, '·'),
(184, '¸'),
(185, '¹'),
(186, 'º'),
(187, '»'),
(188, '¼'),
(189, '½'),
(190, '¾'),
(191, '¿'),
(192, 'À'),
(193, 'Á'),
(194, 'Â'),
(195, 'Ã'),
(196, 'Ä'),
(197, 'Å'),
(198, 'Æ'),
(199, 'Ç'),
(200, 'È'),
(201, 'É'),
(202, 'Ê'),
(203, 'Ë'),
(204, 'Ì'),
(205, 'Í'),
(206, 'Î'),
(207, 'Ï'),
(208, 'Ð'),
(209, 'Ñ'),
(210, 'Ò'),
(211, 'Ó'),
(212, 'Ô'),
(213, 'Õ'),
(214, 'Ö'),
(215, '×'),
(216, 'Ø'),
(217, 'Ù'),
(218, 'Ú'),
(219, 'Û'),
(220, 'Ü'),
(221, 'Ý'),
(222, 'Þ'),
(223, 'ß'),
(224, 'à'),
(225, 'á'),
(226, 'â'),
(227, 'ã'),
(228, 'ä'),
(229, 'å'),
(230, 'æ'),
(231, 'ç'),
(232, 'è'),
(233, 'é'),
(234, 'ê'),
(235, 'ë'),
(236, 'ì'),
(237, 'í'),
(238, 'î'),
(239, 'ï'),
(240, 'ð'),
(241, 'ñ'),
(242, 'ò'),
(243, 'ó'),
(244, 'ô'),
(245, 'õ'),
(246, 'ö'),
(247, '÷'),
(248, 'ø'),
(249, 'ù'),
(250, 'ú'),
(251, 'û'),
(252, 'ü'),
(253, 'ý'),
(254, 'þ'),
(255, 'ÿ'),
(8364, '€');
EDITED:
If you want the euro symbol working (and in general ASCII codes over 255), you will need to use NCHAR instead CHAR in Richard Deeming code.

Related

Available options with current script > Table or View needed (SQL Server)

So, I have the current script below, but I need to create this as a view and I know you can't use variable within it. I understand there is the option of creating a stored procedure, but I'm not quite sure how to go about.
Create View vwPUs__cwa as (
Declare #salt varchar (25);
DECLARE #Seed int;
DECLARE #LCV tinyint;
DECLARE #CTime DATETIME;
SET #CTime = GETDATE();
SET #Seed = (DATEPART(hh, #Ctime) * 10000000) + (DATEPART(n, #CTime) * 100000)
+ (DATEPART(s, #CTime) * 1000) + DATEPART(ms, #CTime);
SET #LCV = 1;
SET #Salt = CHAR(ROUND((RAND(#Seed) * 94.0) + 32, 3));
WHILE (#LCV < 25)
BEGIN
SET #Salt = #Salt + CHAR(ROUND((RAND() * 94.0) + 32, 3));
SET #LCV = #LCV + 1;
END;
SELECT dc.id,
sys.Fn_varbintohexsubstring(0, Hashbytes('SHA2_512', #salt + dc.decrypt),
1, 0)
AS SaltyHashbrowns,
dc.firstname,
dc.lastname,
dc.statusname,
dc.processingunit,
dc.processingunitnumber
FROM vwdecrypt_cwa dc
WHERE dc.processingunitnumber IN ( 0201301, 0201302, 0201303, 0201308,
0201309, 0201311, 0201312 )
;
The Prcoedure you need to create will be along the lines of
create procedure PUs__cwa
as
set nocount on
declare #salt varchar (25), #Seed int, #LCV tinyint=1, #CTime datetime=GetDate()
set #Seed = (DatePart(hh, #CTime) * 10000000) + (DatePart(n, #CTime) * 100000)
+ (DatePart(s, #CTime) * 1000) + DatePart(ms, #CTime);
set #salt = Char(Round((Rand(#Seed) * 94.0) + 32, 3));
while (#LCV < 25)
begin
set #salt = #salt + Char(Round((Rand() * 94.0) + 32, 3));
set #LCV += 1;
end;
select dc.id,
sys.fn_varbintohexsubstring(0, HashBytes('SHA2_512', #salt + dc.decrypt), 1, 0) as SaltyHashbrowns,
dc.firstname,
dc.lastname,
dc.statusname,
dc.processingunit,
dc.processingunitnumber
from vwdecrypt_cwa dc
where dc.processingunitnumber in ( 0201301, 0201302, 0201303, 0201308, 0201309, 0201311, 0201312 )
And you run it in tsql with exec PUs__cwa
An inline Table-Valued Function would work here. It is effectively treated by the compiler as a parameterized view.
You cannot place RAND() in a UDF, so we must do this in a stored procedure and pass it through:
CREATE OR ALTER FUNCTION vwPUs__cwa (#salt varchar (25))
RETURNS TABLE
AS RETURN
(
SELECT dc.id,
sys.Fn_varbintohexsubstring(0, Hashbytes('SHA2_512', #salt + dc.decrypt),
1, 0)
AS SaltyHashbrowns,
dc.firstname,
dc.lastname,
dc.statusname,
dc.processingunit,
dc.processingunitnumber
FROM vwdecrypt_cwa dc
WHERE dc.processingunitnumber IN ( 0201301, 0201302, 0201303, 0201308,
0201309, 0201311, 0201312 )
);
GO
CREATE OR ALTER PROCEDURE PUs__cwa
AS
SET NOCOUNT, XACT_ABORT ON;
DECLARE #salt varchar(25);
DECLARE #Seed int = (DATEPART(hh, #Ctime) * 10000000) + (DATEPART(n, #CTime) * 100000) + (DATEPART(s, #CTime) * 1000) + DATEPART(ms, #CTime);
DECLARE #LCV tinyint = 1;
DECLARE #CTime DATETIME = GETDATE();
WHILE (#LCV < 25)
BEGIN
SET #LCV = #LCV + 1;
SET #Salt = CONCAT(#Salt, CHAR(ROUND((RAND() * 94.0) + 32, 3)));
END;
SELECT *
FROM vwPUs__cwa (#salt);
GO
You could also run the salt code in a client application, and pass it through as a parameter to an ad-hoc batch:
SELECT *
FROM vwPUs__cwa (#salt);

SSIS OLE DB Command error: Could not deduce type for parameter in position '1' for remote call to module 'sp_executesql'

I have an OLE DB Command task in an SSIS package that received parameters, inserts them into a table in a linked-server, and returns the ID that was created on the linked server.
When I run the query in SSMS it works, but within SSIS I get the error message in the suject line.
The SqlCommand within the OLE DB Command is:
DECLARE
#UserId int = ?,
#ContactUsId int = ?,
#CreateDate datetime = ?,
#Subject nvarchar(500) = ?,
#InteractionClusterId int = null -- We will be testing for this being null
-- removed some irrelevant code here
-- if all else failed, insert a new record to MngInteractionCluster
if #InteractionClusterId is null
begin
declare #RemoteQuery nvarchar(max) = N'
insert into BI_Mng.dbo.MngInteractionCluster
(
UserId,
ContactUsId,
CreateDateTime,
[Subject]
)
values
(
#UserId,
#ContactUsId,
#CreateDate,
#Subject
)
SELECT #InteractionClusterId_OUT = SCOPE_IDENTITY()'
declare #Params nvarchar(1000) = N'
#UserId int,
#ContactUsId int,
#CreateDate datetime,
#Subject nvarchar(500),
#InteractionClusterId_OUT int OUTPUT'
EXEC [BI_WAREHOUSE\BI_GLOBAL].master.dbo.sp_executesql
#RemoteQuery,
#Params,
#UserId = #UserId ,
#ContactUsId = #ContactUsId,
#CreateDate = #CreateDate,
#Subject = #Subject,
#InteractionClusterId_OUT = #InteractionClusterId OUTPUT;
end
select
? = #InteractionClusterId
Any help on getting this to parse in SSIS would be really appreciated!
I ended up moving the heavy lifting into a stored procedure on the local server.
Now the code in the OLE DB command component is a concise
DECLARE
#OriginalMailId int = ?,
#UserId int = ?,
#ContactUsId int = ?,
#CreateDate datetime = ?,
#Subject nvarchar(500) = ?,
#isAutoReply bit = ?,
#BIEnvironmentId int = ?,
#InteractionClusterId int
exec BI_Mng.dbo.GetInteractionClusterId
#OriginalMailId,
#UserId,
#ContactUsId,
#CreateDate,
#Subject,
#isAutoReply,
#BIEnvironmentId,
#InteractionClusterId OUTPUT
select ? = #InteractionClusterId
Inside the stored procedure there's a call to a remote execution of sp_ExecuteSQL on the linked server. In order for SSIS to parse it, it's vital that it include a WITH RESULT SETS clause, like so:
declare #RemoteQuery nvarchar(max) = N'
insert into BI_Mng.dbo.MngInteractionCluster
(
UserId,
ContactUsId,
CreateDateTime,
[Subject]
)
values
(
#UserId,
#ContactUsId,
#CreateDate,
#Subject
)
SELECT #InteractionClusterId_OUT = SCOPE_IDENTITY()'
declare #Params nvarchar(1000) = N'
#UserId int,
#ContactUsId int,
#CreateDate datetime,
#Subject nvarchar(500),
#InteractionClusterId_OUT int OUTPUT'
EXEC [BI_WAREHOUSE\BI_GLOBAL].master.dbo.sp_executesql
#RemoteQuery,
#Params,
#UserId = #UserId ,
#ContactUsId = #ContactUsId,
#CreateDate = #CreateDate,
#Subject = #Subject,
#InteractionClusterId_OUT = #InteractionClusterId OUTPUT
WITH RESULT SETS NONE;

SQL OLE Automation Granting Access To A Linux Share

I'm pretty desperate for some guidance on this.
I've been running for years a SQL function that uses OLE Automation to retrieve file statistics in an important workflow.
Recently a NAS vendor i have changed their firmware breaking "Guest Access". The NAS throws "access denied" errors now. After troubleshooting, the vendor is resisting fixing this, instructing me to "get my program to pass credentials."
I have a windows credential setup but apparently that is now what's being used under the hood here.
How can i pass credentials from my linux based nas when using OLE Automation?
The code is below for reference.
CREATE FUNCTION [dbo].[ufn_fileOperation]
(
#filPath VARCHAR (500),
#flg TINYINT = 1 -- 1 Select, 2 Stream, 3 Delete
)
RETURNS
#var TABLE
(
[FileName] varchar (500)
, [Type] varchar (200)
, [CreatedDate] datetime
, [LastAsscessedDate] datetime
, [LastModifiedDate] datetime
, [FullPath] varchar (500)
, [ShortPath] varchar (500)
, [Attribute] int
, [Operation] varchar(10)
, [FileText] varchar(max)
)
AS
BEGIN
DECLARE #init INT,
#fso INT,
#objFile INT,
#errObj INT,
#errMsg VARCHAR (500),
#fullPath VARCHAR (500),
#shortPath VARCHAR (500),
#objType VARCHAR (500),
#dateCreated datetime,
#dateLastAccessed datetime,
#dateLastModified datetime,
#attribute INT,
#objSize INT,
#fileName varchar (500),
#operation varchar(10),
#objStream INT,
#string varchar(max) = '',
#stringChunk varchar(8000),
#qBreak INT
SELECT
#init = 0,
#errMsg = 'Step01: File Open'
EXEC #init = sp_OACreate 'Scripting.FileSystemObject',
#fso OUT
IF #init = 0 SELECT
#errMsg = 'Step02: File Access '''
+ #filPath + '''',
#errObj = #fso
IF #init = 0 EXEC #init = sp_OAMethod #fso,
'GetFile',
#objFile OUT,
#filPath
IF #init = 0
SELECT
#errMsg = 'Step03: Access Attributes'''
+ #filPath + '''',
#errObj = #objFile
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'Name',
#fileName OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'Type',
#objType OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'DateCreated',
#dateCreated OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'DateLastAccessed',
#dateLastAccessed OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'DateLastModified',
#dateLastModified OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'Attributes',
#attribute OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'size',
#objSize OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'Path',
#fullPath OUT
IF #init = 0 EXEC #init = sp_OAGetProperty #objFile,
'ShortPath',
#shortPath OUT
EXEC sp_OADestroy #fso
EXEC sp_OADestroy #objFile
SELECT #fso = NULL, #objFile = NULL, #operation = 'Selected'
IF #flg = 2
BEGIN
EXECUTE #init = sp_OACreate 'Scripting.FileSystemObject' , #fso OUT
IF #init=0 EXECUTE #init = sp_OAMethod #fso,
'OpenTextFile',
#objStream OUT,
#fullPath,
1,
false,
0
WHILE #init = 0
BEGIN
IF #init = 0 EXECUTE #init = sp_OAGetProperty #objStream, 'AtEndOfStream', #qBreak OUTPUT
IF #qBreak <> 0 BREAK
IF #init = 0 EXECUTE #init = sp_OAMethod #objStream, 'Read', #stringChunk OUTPUT,4000
SELECT #String=#string+#stringChunk
END
IF #init=0 EXECUTE #init = sp_OAMethod #objStream, 'Close'
EXECUTE sp_OADestroy #objStream
EXEC sp_OADestroy #fso
SET #operation = 'Stream'
END
SELECT #fso = NULL, #objFile = NULL
IF #flg = 3
BEGIN
EXEC #init = sp_OACreate 'Scripting.FileSystemObject', #fso OUTPUT
EXEC #init = sp_OAMethod #fso, 'DeleteFile', NULL, #fullPath
EXEC #init = sp_OADestroy #fso
SELECT #operation = 'Deleted'
END
INSERT INTO #var
VALUES (#fileName, #objType, #dateCreated, #dateLastAccessed, #dateLastModified, #fullPath, #shortPath, #attribute, #operation, #string)
RETURN
END

Incorrect syntax near the keyword 'FOR' XML

I get the error
Incorrect syntax near the keyword 'FOR'
when I write '+# SirketNo+' to the dot.
I could not find the error.
Error :
Msg 156, Level 15, State 1, Line 110
Incorrect syntax near the keyword 'FOR'
Msg 102, Level 15, State 1, Line 125
Incorrect syntax near ','
Msg 102, Level 15, State 1, Line 137
Incorrect syntax near ','
My code:
DECLARE #SirketNo AS NVARCHAR(3)= '427',
#AliciAdreslerinDepartmani AS NVARCHAR(MAX) = 'MuhasebeMuduru',
#BilgiAliciAdreslerinDepartmani AS NVARCHAR(MAX) = 'Mudur',
#GizliAliciAdreslerinDepartmani AS NVARCHAR(MAX) = 'FinansKoordinatoru'', ''FinansSorumlusu'', ''Developer';
DECLARE #SqlQuery AS NVARCHAR(max) = N'
BEGIN
DECLARE #KacGunOnce INT= 13, #xml NVARCHAR(MAX), #KasaBakiye NVARCHAR(MAX), #AliciAdresler VARCHAR(MAX), #BilgiAliciAdresler VARCHAR(MAX), #GizliBilgiAliciAdresler VARCHAR(MAX), #vucut NVARCHAR(MAX), #Baslik VARCHAR(100)= '''', #CreatedBy VARCHAR(100)= '''', #Mesaj VARCHAR(250)= '''', #IsYeriNo SMALLINT;
DECLARE #mad TABLE
(logicalref INT IDENTITY(1, 1),
IsYeriNo SMALLINT,
KasaKodu VARCHAR(17),
KasaAdi VARCHAR(51),
AlıcıAdresler NVARCHAR(MAX),
BilgiAlıcıAdresler NVARCHAR(MAX),
GizliBilgiAlıcıAdresler NVARCHAR(MAX)
);
END; --Değişkenleri ve değişken tabloyu oluştur
BEGIN
INSERT INTO #mad
(IsYeriNo,
KasaKodu,
KasaAdi
)
SELECT DISTINCT
ksl.BRANCH,
lk.CODE,
lk.NAME
FROM LG_'+#SirketNo+'_01_KSLINES AS KSL WITH (NOLOCK)
JOIN L_CAPIUSER AS U WITH (NOLOCK) ON U.NR LIKE KSL.CAPIBLOCK_CREATEDBY
JOIN LG_'+#SirketNo+'_KSCARD AS lk ON lk.LOGICALREF = ksl.CARDREF
WHERE ksl.SIGN = 1
AND ksl.AMOUNT >= 300
AND CONVERT(VARCHAR(10), ksl.DATE_, 104) = CONVERT(VARCHAR(10), GETDATE() - #KacGunOnce, 104);
END; --Değişken tabloya verileri insert et
BEGIN
--Döngü için değişken atamaları
DECLARE #s INT= 1, #d INT=
(
SELECT COUNT(logicalref)
FROM #mad
);
--Döngü
WHILE #d >= #s
BEGIN
/**** DÖNGÜ BAŞLANGIÇ ****/
BEGIN
SELECT #KasaBakiye =
(
SELECT KasaKodu
FROM #mad
WHERE logicalref = #s
)+'' kodlu kasanın güncel bakiyesi: ''+FORMAT(SUM(CASHTOT.DEBIT - CASHTOT.CREDIT), ''c2'', ''tr-TR'')
FROM LG_'+#SirketNo+'_KSCARD AS CASHC WITH (NOLOCK),
LG_'+#SirketNo+'_01_CSHTOTS AS CASHTOT WITH (NOLOCK)
WHERE CASHC.CODE LIKE
(
SELECT KasaKodu
FROM #mad
WHERE logicalref = #s
)
AND CASHTOT.CARDREF = CASHC.LOGICALREF
AND CASHTOT.TOTTYPE = 1
AND CASHTOT.DAY_ >= 0
AND CASHTOT.DAY_ <= 365;
END; --Kasa Bakiyesini değişkene ata
BEGIN
-- İş yerini değişkene ata
SELECT #IsYeriNo = IsYeriNo
FROM #mad
WHERE logicalref = #s;
END; -- İş yerini değişkene ata;
BEGIN --Kasa hareketlerini HTML formatında XMLe dönüştür
SET #xml = CAST(
(
SELECT f.DATE_ AS ''td'',
'''',
f.FICHENO AS ''td'',
'''',
f.TRCODE AS ''td'',
'''',
f.CUSTTITLE AS ''td'',
'''',
f.LINEEXP AS ''td'',
'''',
f.AMOUNT AS ''td'',
'''',
f.REPORTRATE AS ''td'',
'''',
f.REPORTNET AS ''td'',
'''',
f.SPECODE AS ''td'',
'''',
f.CYPHCODE AS ''td'',
'''',
f.BRANCH AS ''td'',
'''',
f.NAME AS ''td'',
''''
FROM
(
SELECT ksl.DATE_,
KSL.FICHENO,
CASE TRCODE
WHEN 11
THEN ''CARİ HESAP TAHSİLAT''
WHEN 12
THEN ''CARİ İŞLEM''
WHEN 21
THEN ''BANKA İŞLEMİ''
WHEN 22
THEN ''BANKA İŞLEMİ''
WHEN 31
THEN ''FATURA İŞLEMİ''
WHEN 32
THEN ''FATURA İŞLEMİ''
WHEN 33
THEN ''FATURA İŞLEMİ''
WHEN 34
THEN ''FATURA İŞLEMİ''
WHEN 35
THEN ''FATURA İŞLEMİ''
WHEN 36
THEN ''FATURA İŞLEMİ''
WHEN 37
THEN ''FATURA İŞLEMİ''
WHEN 38
THEN ''FATURA İŞLEMİ''
WHEN 39
THEN ''FATURA İŞLEMİ''
WHEN 61
THEN ''ÇEK-SENET İŞLEMİ''
WHEN 62
THEN ''ÇEK-SENET İŞLEMİ''
WHEN 63
THEN ''ÇEK-SENET İŞLEMİ''
WHEN 64
THEN ''ÇEK-SENET İŞLEMİ''
WHEN 71
THEN ''KASA İŞLEMİ''
WHEN 72
THEN ''KASA İŞLEMİ''
WHEN 73
THEN ''KASA İŞLEMİ''
WHEN 74
THEN ''KASA İŞLEMİ''
ELSE ''TANIMSIZ İŞLEM''
END AS ''TRCODE'',
KSL.CUSTTITLE,
KSL.LINEEXP,
FORMAT(AMOUNT, ''c2'', ''tr-TR'') AS ''AMOUNT'',
CAST(REPORTRATE AS MONEY) AS ''REPORTRATE'',
CAST(REPORTNET AS MONEY) AS ''REPORTNET'',
KSL.SPECODE,
KSL.CYPHCODE,
KSL.BRANCH,
U.NAME
FROM LG_'+#SirketNo+'_01_KSLINES AS KSL WITH (NOLOCK) /**************************************/
JOIN L_CAPIUSER AS U WITH (NOLOCK) ON U.NR LIKE KSL.CAPIBLOCK_CREATEDBY
JOIN LG_427_KSCARD AS lk ON lk.LOGICALREF = ksl.CARDREF
WHERE ksl.SIGN = 1
AND ksl.AMOUNT >= 300
AND CONVERT(VARCHAR(10), ksl.DATE_, 104) = CONVERT(VARCHAR(10), GETDATE() - #KacGunOnce, 104)
AND ksl.BRANCH =
(
SELECT IsYeriNo
FROM #mad
WHERE logicalref = #s
)
AND lk.CODE =
(
SELECT KasaKodu
FROM #mad
WHERE logicalref = #s
)
) AS f
FOR XML PATH(''tr''), ELEMENTS
) AS NVARCHAR(max));
END; --Kasa hareketlerini HTML formatında XML''e dönüştür
BEGIN
UPDATE #mad
SET
[AlıcıAdresler] = ISNULL(
(
SELECT TOP 1 REPLACE(
(
SELECT RTRIM(MAIL) [data()]
FROM mad.dbo.Kullanicilar k
WHERE k.SIRKET = ''427''
AND IS_YERI = #IsYeriNo
AND LEN(MAIL) > 0
AND DEPERTMAN IN('''+#AliciAdreslerinDepartmani+''')
FOR XML PATH('''')
), '' '', ''; '') AS BIRLESIK
), ''''),
[BilgiAlıcıAdresler] = ISNULL(
(
SELECT TOP 1 REPLACE(
(
SELECT RTRIM(MAIL) [data()]
FROM mad.dbo.Kullanicilar k
WHERE k.SIRKET = ''427''
AND IS_YERI = #IsYeriNo
AND LEN(MAIL) > 0
AND DEPERTMAN IN('''+#BilgiAliciAdreslerinDepartmani+''')
FOR XML PATH('''')
), '' '', ''; '') AS BIRLESIK
), ''''),
[GizliBilgiAlıcıAdresler] = ISNULL(
(
SELECT TOP 1 REPLACE(
(
SELECT RTRIM(MAIL) [data()]
FROM mad.dbo.Kullanicilar k
WHERE k.SIRKET = ''427''
AND LEN(MAIL) > 0
AND DEPERTMAN IN('''+#GizliAliciAdreslerinDepartmani+''')
FOR XML PATH('''')
), '' '', ''; '') AS BIRLESIK
), '''')
WHERE IsYeriNo = #IsYeriNo;
END; -- Değişken tabloya mail adreslerini update et
BEGIN
UPDATE #mad
SET
[AlıcıAdresler] = [BilgiAlıcıAdresler]
WHERE [AlıcıAdresler] = '''';
END; -- Değişken tabloda alici adresi boş olanlara bilgideki adresleri alici olarak ekle
BEGIN
SET #Baslik = '''';
SET #Mesaj = '''';
SET #vucut = '''';
SELECT #Baslik+=CONVERT( NVARCHAR, #IsYeriNo)+'' nolu işyerinin kasa hareketleridir. [212]'';
SELECT #Mesaj+='''';
SET #vucut = ''<html>''+''<body>''+''<H3 style = "color:blue;"><i>''+#Mesaj+''</i> </H3>''+''<H2 style="text-align:center; color:orange;"> Kasa Hareketleri </H2>''+''<H4> ''+''<ul style = "list-style-type:disc">''+''<p>''+''<li>''+#KasaBakiye+''</li>''+''</ul>''+''</p>''+''<H4> ''+''
<table border = 1>
<tr>
<th> Tarih </th> <th> Fiş No </th> <th> İşlem Türü </th> <th> Cari Başlığı </th> <th> Açıklama </th> <th> Tutar </th> <th> Kur </th> <th> Döviz Tutar </th> <th> Özel Kodu </th> <th> Yetki Kodu </th> <th> İş Yeri </th> <th> Kaydeden Kullanıcı </th>
</tr>'';
SET #vucut = #vucut+#xml+''</table></body></html>''+''[''+CONVERT(NVARCHAR, #IsYeriNo)+'' nolu işyerinin ''+
(
SELECT KasaKodu
FROM #mad
WHERE logicalref = #s
)+'' kodlu kasanın ''+CONVERT(NVARCHAR, #KacGunOnce)+'' gün öncesine ait hareketleridir.] Bu maile cevap vererek bilgilendirme maili ile alakalı tavsiyenizi yazabilirsiniz.'';
END; --Mail verilerini hazırla
BEGIN
SET #AliciAdresler =
(
SELECT m.[AlıcıAdresler]
FROM #mad m
WHERE m.logicalref = #s
);
SET #BilgiAliciAdresler =
(
SELECT m.[BilgiAlıcıAdresler]
FROM #mad m
WHERE m.logicalref = #s
);
SET #GizliBilgiAliciAdresler =
(
SELECT m.[GizliBilgiAlıcıAdresler]
FROM #mad m
WHERE m.logicalref = #s
);
END; -- Mail adreslerini değişkenlere tanımla
BEGIN
EXEC msdb.dbo.sp_send_dbmail
#body = #vucut,
#body_format = ''HTML'',
#subject = #Baslik,
#importance = ''HIGH'',
#reply_to = ''mustafaalperen#fimar.com.tr'',
#profile_name = ''MAD_Mail'',
--#recipients = #AliciAdresler,
--#copy_recipients = #BilgiAliciAdresler,
#blind_copy_recipients = #GizliBilgiAliciAdresler,
#execute_query_database = ''FIMAR_MHB'';
END; --Mail Gönder
BEGIN
DECLARE #GonderilenMailBilgisi NVARCHAR(MAX)= ''Mail (Id: ''+CONVERT(NVARCHAR, ##IDENTITY)+'') queued.'';
EXEC sp_MAD_Loglar_Ins
#FORM = ''AGENT_MAD_08_00_Mailleri'',
#KULLANICI = ''Sql Agent'',
#TERMINAL = ''427'',
#ASISTAN = #GonderilenMailBilgisi,
#DERECE = ''Bal'';
END; --Loglama yap
BEGIN
SET #s = #s + 1;
END; --Döngü için döngü değişkenini +1 arttır
/**** DÖNGÜ BİTİŞ ****/
END;
END; -- Mail gönderme döngüsü
';
EXECUTE sp_executesql #SqlQuery;
Consider changing your database design and minimize the use of dynamic SQL. Now your dynamic SQL code will allways be prone to mystical errors and SQL injection attacks.
As suggested by #PPP, you have to get the generated code and see what is wrong with it - to debug it in SQL Server Management Studio.
To do it, you have to use this command:
PRINT CAST(#SqlQuery as ntext)
because your dynamically generated sql is longer than 8000 chars. See this question.
Then copy it to a new window and see the syntax errors and fix them and then fix the code that generates it appropriately.

IF EXISTS UPSERT

I currently have a stored procedure that updates files if they exist and inserts if they don't. The problem with the query below is it seem to be inserting all records regardless.
I can't seem to spot what the problem is?
Using SQL server 2012
ALTER PROC [dbo].[usp_UpdateInsertOptimise_new]
#Resid int = null,
#PostCode varchar(50),
#DriverID int,
#droporder int,
#X int,
#Y int,
#Calculate bit,
#uidref bigint,
#Description1 varchar(500),
#Description2 varchar(500),
#Description3 varchar(500),
#Uiddriver int,
#reservationsid int,
#Time varchar(50),
#TimeInPoint int,
#UniqueString varchar(50),
#DistanceBetweenTwoPoints float,
#Weight int,
#TimeBetweenPoints int,
#TimeFrom datetime,
#TimeTo datetime,
#TotalDistance float,
#Display varchar(150),
#Volume float,
#VehicleID int,
#Pallets int,
#AddressId int,
#CD nvarchar(10),
#ForkLiftRequired bit,
#HazardousRequired bit,
#FridgeRequired bit,
#TailLiftRequired bit,
#CurtinsideRequired bit,
#CDID varchar(50),
#CDOrder int,
#OriginalDate datetime,
#ArivalTime datetime,
#TimeForStage int,
#Optimise bit,
#ForVehicleGroupID int,
#DepotID int
AS
if EXISTS (SELECT * FROM optimise WITH (READUNCOMMITTED)
Where ReservationsID = #ResID)
BEGIN
UPDATE dbo.Optimise SET
PostCode = #PostCode,
[DriverID] = #DriverID,
[droporder] = #DropOrder,
[X] = #X,
[Y] = #Y,
[Calculate] = #Calculate,
[uidref] = #UIDRef,
[Description1] = #Description1,
[Description2] = #Description2,
[Description3] = #Description3,
[Uiddriver] = #UIDDriver,
[reservationsid] = #ReservationsID,
[Time] = #Time,
[TimeInPoint] = #TimeInPoint,
[UniqueString] = #UniqueString,
[DistanceBetweenTwoPoints] = #DistanceBetweenTwoPoints,
[Weight] = #Weight,
[TimeBetweenPoints] = #TimeBetweenPoints,
[TimeFrom] = #TimeFrom,
[TimeTo] = #TimeTo,
[TotalDistance] = #TotalDistance,
[Display] = #Display,
[Volume] = #Volume,
[VehicleID] = #VehicleID,
[Pallets] = #Pallets,
[AddressID] = #AddressID,
[CD] = #CD,
[ForkliftRequired] = #ForkLiftRequired,
[HazardousRequired] = #HazardousRequired,
[FridgeRequired] = #FridgeRequired,
[TailLiftRequired] = #TailLiftRequired,
[CurtinsideRequired] = #CurtinsideRequired,
[CDID] = #CDID,
[CDOrder] = #CDOrder,
[OriginalDate] = #OriginalDate,
[ArivalTime] = #ArivalTime,
[TimeForStage] = #TimeForStage,
[Optimise] = #Optimise,
[ForVehicleGroupID] = #ForVehicleGroupID,
[DepotID] = #DepotID
WHERE ReservationsID = #ResID
END
ELSE
IF NOT EXISTs(SELECT * FROM optimise WITH (READUNCOMMITTED)
Where ReservationsID = #ResID)
BEGIN
INSERT INTO [Optimise]
([PostCode],
[DriverID],
[droporder],
[X],
[Y],
[Calculate],
[uidref],
[Description1],
[Description2],
[Description3],
[Uiddriver],
[reservationsid],
[Time],
[TimeInPoint],
[UniqueString],
[DistanceBetweenTwoPoints],
[Weight],
[TimeBetweenPoints],
[TimeFrom],
[TimeTo],
[TotalDistance],
[Display],
[Volume],
[VehicleID],
[Pallets],
[AddressId],
[CD],
[ForkliftRequired],
[HazardousRequired],
[FridgeRequired],
[TailLiftRequired],
[CurtinsideRequired],
[CDID],
[CDOrder],
[OriginalDate],
[ArivalTime],
[TimeForStage],
[Optimise],
[ForVehicleGroupID],
[DepotID] )
VALUES (
#PostCode,
#DriverID,
#DropOrder,
#X,
#Y,
#Calculate,
#UIDRef,
#Description1,
#Description2,
#Description3,
#UIDDriver,
#ReservationsID,
#Time,
#TimeInPoint,
#UniqueString,
#DistanceBetweenTwoPoints,
#Weight,
#TimeBetweenPoints,
#TimeFrom,
#TimeTo,
#TotalDistance,
#Display,
#Volume,
#VehicleID,
#Pallets,
#AddressId,
#CD,
#ForkLiftRequired,
#HazardousRequired,
#FridgeRequired,
#TailLiftRequired,
#CurtinsideRequired,
#CDID,
#CDOrder,
#OriginalDate,
#ArivalTime,
#TimeForStage,
#Optimise,
#ForVehicleGroupID,
#DepotID)
END
GO
I Can't see anything wrong at all so sorry if this seems patronising, back to basics though:
Are you calling the correct SP? I notice the SP above is appended with _new usp_UpdateInsertOptimise_new
Are you passing the correct ResIDs? Do they exist, have you traced these when calling the proc.
simplify the proc to return a true/false, see which fires, remove anything not essential to just check if the ID exists or not. try switching IF EXISTS for IF NOT EXISTS see what happens.
#ResID is defaulted to null at the top. No idea why, it didn't work because of it though!