IF EXISTS UPSERT - sql

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!

Related

Microsoft SQL query to view

I have this complex query that i want to turn into a view.
This query comes from https://snippets.cacher.io/snippet/3e84b01b7d52b4ca7807 and i want to save it in a view or even as a table if possible.
`
/*##=============================================*/
/*## QUERY BODY */
/*##=============================================*/
/* #region QueryBody */
/* Testing variables !! Need to be commented for Production !! */
-- DECLARE #UserSIDs AS NVARCHAR(10) = 'Disabled';
-- DECLARE #CollectionID AS NVARCHAR(10) = 'SMS00001';
-- DECLARE #Locale AS INT = 2;
-- DECLARE #Categories AS NVARCHAR(250) = 'Tools';
-- DECLARE #Compliant AS INT = 0;
-- DECLARE #Targeted AS INT = 1;
-- DECLARE #Superseded AS INT = 0;
-- DECLARE #ArticleID AS NVARCHAR(10) = '';
-- DECLARE #ExcludeArticleIDs AS NVARCHAR(250) = '';
/* Variable declaration */
DECLARE #LCID AS INT = dbo.fn_LShortNameToLCID(#Locale);
DECLARE #HelperFunctionExists AS INT = 0;
/* Perform cleanup */
IF OBJECT_ID('tempdb..#MaintenanceInfo', 'U') IS NOT NULL
DROP TABLE #MaintenanceInfo;
/* Check for helper function */
IF OBJECT_ID('[dbo].[ufn_CM_GetNextMaintenanceWindow]') IS NOT NULL
SET #HelperFunctionExists = 1;
/* Initialize HealthState descriptor table */
DECLARE #HealthState TABLE (
BitMask INT
, StateName NVARCHAR(250)
)
/* Populate HealthState table */
INSERT INTO #HealthState (BitMask, StateName)
VALUES
('0', 'Healthy')
, ('1', 'Unmanaged')
, ('2', 'Inactive')
, ('4', 'Health Evaluation Failed')
, ('8', 'Pending Restart')
, ('16', 'Update Scan Failed')
, ('32', 'Update Scan Late')
, ('64', 'No Maintenance Window')
, ('128', 'Distant Maintenance Window')
, ('256', 'Expired Maintenance Window')
/* Initialize ClientState descriptor table */
DECLARE #ClientState TABLE (
BitMask INT
, StateName NVARCHAR(100)
)
/* Populate ClientState table */
INSERT INTO #ClientState (BitMask, StateName)
VALUES
('0', 'No Reboot')
, ('1', 'Configuration Manager')
, ('2', 'File Rename')
, ('4', 'Windows Update')
, ('8', 'Add or Remove Feature')
CREATE TABLE #MaintenanceInfo (
ResourceID INT
, NextServiceWindow DATETIME
)
/* Get maintenance data */
IF #HelperFunctionExists = 1
BEGIN
WITH Maintenance_CTE AS (
SELECT
CollectionMembers.ResourceID
, NextServiceWindow.Duration
, NextServiceWindow.NextServiceWindow
, RowNumber = DENSE_RANK() OVER (PARTITION BY ResourceID ORDER BY NextServiceWindow.NextServiceWindow)
, ServiceWindowType
, ServiceWindow.Enabled
FROM vSMS_ServiceWindow AS ServiceWindow
JOIN fn_rbac_FullCollectionMembership(#UserSIDs) AS CollectionMembers ON CollectionMembers.CollectionID = ServiceWindow.SiteID
JOIN fn_rbac_Collection(#UserSIDs) AS Collections ON Collections.CollectionID = CollectionMembers.CollectionID
AND Collections.CollectionType = 2 -- Device Collections
CROSS APPLY ufn_CM_GetNextMaintenanceWindow(ServiceWindow.Schedules, ServiceWindow.RecurrenceType) AS NextServiceWindow
WHERE NextServiceWindow.NextServiceWindow IS NOT NULL
AND ServiceWindowType <> 5 -- OSD Service
)
/* Populate MaintenanceInfo table and remove duplicates */
INSERT INTO #MaintenanceInfo(ResourceID, NextServiceWindow)
SELECT
ResourceID
, NextServiceWindow
FROM Maintenance_CTE
WHERE RowNumber = 1
END
/* Get update data */
;
WITH UpdateInfo_CTE
AS (
SELECT
ResourceID = Systems.ResourceID
, Missing = COUNT(*)
FROM fn_rbac_R_System(#UserSIDs) AS Systems
JOIN fn_rbac_UpdateComplianceStatus(#UserSIDs) AS ComplianceStatus ON ComplianceStatus.ResourceID = Systems.ResourceID
AND ComplianceStatus.Status = 2 -- Filter on 'Required' (0 = Unknown, 1 = NotRequired, 2 = Required, 3 = Installed)
JOIN fn_rbac_ClientCollectionMembers(#UserSIDs) AS CollectionMembers ON CollectionMembers.ResourceID = ComplianceStatus.ResourceID
JOIN fn_rbac_UpdateInfo(#LCID, #UserSIDs) AS UpdateCIs ON UpdateCIs.CI_ID = ComplianceStatus.CI_ID
AND UpdateCIs.IsSuperseded IN (#Superseded)
AND UpdateCIs.CIType_ID IN (1, 8) -- Filter on 1 Software Updates, 8 Software Update Bundle (v_CITypes)
AND UpdateCIs.ArticleID NOT IN ( -- Filter on ArticleID csv list
SELECT VALUE FROM STRING_SPLIT(#ExcludeArticleIDs, ',')
)
AND UpdateCIs.Title NOT LIKE ( -- Filter Preview updates
'[1-9][0-9][0-9][0-9]-[0-9][0-9]_Preview_of_%'
)
JOIN fn_rbac_CICategoryInfo_All(#LCID, #UserSIDs) AS CICategory ON CICategory.CI_ID = ComplianceStatus.CI_ID
AND CICategory.CategoryTypeName = 'UpdateClassification'
AND CICategory.CategoryInstanceName IN (#Categories) -- Filter on Selected Update Classification Categories
LEFT JOIN fn_rbac_CITargetedMachines(#UserSIDs) AS Targeted ON Targeted.ResourceID = ComplianceStatus.ResourceID
AND Targeted.CI_ID = ComplianceStatus.CI_ID
WHERE CollectionMembers.CollectionID = #CollectionID
AND IIF(Targeted.ResourceID IS NULL, 0, 1) IN (#Targeted) -- Filter on 'Targeted' or 'NotTargeted'
AND IIF(UpdateCIs.ArticleID = #ArticleID, 1, 0) = IIF(#ArticleID <> '', 1, 0)
GROUP BY
Systems.ResourceID
)
/* Get device info */
SELECT
Systems.ResourceID
/* Set Health states. You can find the coresponding values in the HealthState table above */
, HealthStates = (
IIF(CombinedResources.IsClient != 1, POWER(1, 1), 0)
+
IIF(
ClientSummary.ClientStateDescription = 'Inactive/Pass'
OR
ClientSummary.ClientStateDescription = 'Inactive/Fail'
OR
ClientSummary.ClientStateDescription = 'Inactive/Unknown'
, POWER(2, 1), 0)
+
IIF(
ClientSummary.ClientStateDescription = 'Active/Fail'
OR
ClientSummary.ClientStateDescription = 'Inactive/Fail'
, POWER(4, 1), 0
)
+
IIF(CombinedResources.ClientState != 0, POWER(8, 1), 0)
+
IIF(UpdateScan.LastErrorCode != 0, POWER(16, 1), 0)
+
IIF(UpdateScan.LastScanTime < (SELECT DATEADD(dd, -14, CURRENT_TIMESTAMP)), POWER(32, 1), 0)
+
IIF(ISNULL(NextServiceWindow, 0) = 0 AND #HelperFunctionExists = 1, POWER(64, 1), 0)
+
IIF(NextServiceWindow > (SELECT DATEADD(dd, 30, CURRENT_TIMESTAMP)), POWER(128, 1), 0)
+
IIF(NextServiceWindow < (CURRENT_TIMESTAMP), POWER(256, 1), 0)
)
, Missing = ISNULL(Missing, (IIF(CombinedResources.IsClient = 1, 0, NULL)))
, Device = (
IIF(
SystemNames.Resource_Names0 IS NOT NULL, UPPER(SystemNames.Resource_Names0)
, IIF(Systems.Full_Domain_Name0 IS NOT NULL, Systems.Name0 + '.' + Systems.Full_Domain_Name0, Systems.Name0)
)
)
, OperatingSystem = (
CASE
WHEN OperatingSystem.Caption0 != '' THEN
CONCAT(
REPLACE(OperatingSystem.Caption0, 'Microsoft ', ''), -- Remove 'Microsoft ' from OperatingSystem
REPLACE(OperatingSystem.CSDVersion0, 'Service Pack ', ' SP') -- Replace 'Service Pack ' with ' SP' in OperatingSystem
)
ELSE (
/* Workaround for systems not in GS_OPERATING_SYSTEM table */
CASE
WHEN CombinedResources.DeviceOS LIKE '%Workstation 6.1%' THEN 'Windows 7'
WHEN CombinedResources.DeviceOS LIKE '%Workstation 6.2%' THEN 'Windows 8'
WHEN CombinedResources.DeviceOS LIKE '%Workstation 6.3%' THEN 'Windows 8.1'
WHEN CombinedResources.DeviceOS LIKE '%Workstation 10.0%' THEN 'Windows 10'
WHEN CombinedResources.DeviceOS LIKE '%Server 6.0' THEN 'Windows Server 2008'
WHEN CombinedResources.DeviceOS LIKE '%Server 6.1' THEN 'Windows Server 2008R2'
WHEN CombinedResources.DeviceOS LIKE '%Server 6.2' THEN 'Windows Server 2012'
WHEN CombinedResources.DeviceOS LIKE '%Server 6.3' THEN 'Windows Server 2012 R2'
WHEN Systems.Operating_System_Name_And0 LIKE '%Server 10%' THEN (
CASE
WHEN CAST(REPLACE(Build01, '.', '') AS INTEGER) > 10017763 THEN 'Windows Server 2019'
ELSE 'Windows Server 2016'
END
)
ELSE Systems.Operating_System_Name_And0
END
)
END
)
, LastBootTime = (
CONVERT(NVARCHAR(16), OperatingSystem.LastBootUpTime0, 120)
)
, PendingRestart = (
CASE
WHEN CombinedResources.IsClient = 0
OR CombinedResources.ClientState = 0
THEN NULL
ELSE (
STUFF(
REPLACE(
(
SELECT '#!' + LTRIM(RTRIM(StateName)) AS [data()]
FROM #ClientState
WHERE BitMask & CombinedResources.ClientState <> 0
FOR XML PATH('')
),
' #!',', '
),
1, 2, ''
)
)
END
)
, ClientState = (
CASE CombinedResources.IsClient
WHEN 1 THEN ClientSummary.ClientStateDescription
ELSE 'Unmanaged'
END
)
, ClientVersion = CombinedResources.ClientVersion
, LastUpdateScan = (
CONVERT(NVARCHAR(16), UpdateScan.LastScanTime, 120)
)
, LastScanLocation = NULLIF(UpdateScan.LastScanPackageLocation, '')
, LastScanError = NULLIF(UpdateScan.LastErrorCode, 0)
, NextServiceWindow = IIF(CombinedResources.IsClient != 1, NULL, CONVERT(NVARCHAR(16), NextServiceWindow, 120))
FROM fn_rbac_R_System(#UserSIDs) AS Systems
JOIN fn_rbac_CombinedDeviceResources(#UserSIDs) AS CombinedResources ON CombinedResources.MachineID = Systems.ResourceID
LEFT JOIN fn_rbac_RA_System_ResourceNames(#UserSIDs) AS SystemNames ON SystemNames.ResourceID = Systems.ResourceID
LEFT JOIN fn_rbac_GS_OPERATING_SYSTEM(#UserSIDs) AS OperatingSystem ON OperatingSystem.ResourceID = Systems.ResourceID
LEFT JOIN fn_rbac_CH_ClientSummary(#UserSIDs) AS ClientSummary ON ClientSummary.ResourceID = Systems.ResourceID
LEFT JOIN fn_rbac_UpdateScanStatus(#UserSIDs) AS UpdateScan ON UpdateScan.ResourceID = Systems.ResourceID
LEFT JOIN #MaintenanceInfo AS Maintenance ON Maintenance.ResourceID = Systems.ResourceID
LEFT JOIN UpdateInfo_CTE AS UpdateInfo ON UpdateInfo.ResourceID = Systems.ResourceID
JOIN fn_rbac_FullCollectionMembership(#UserSIDs) AS CollectionMembers ON CollectionMembers.ResourceID = Systems.ResourceID
WHERE CollectionMembers.CollectionID = #CollectionID
AND (
CASE -- Compliant (0 = No, 1 = Yes, 2 = Unknown)
WHEN Missing = 0 OR (Missing IS NULL AND Systems.Client0 = 1) THEN 1 -- Yes
WHEN Missing > 0 AND Missing IS NOT NULL THEN 0 -- No
ELSE 2 -- Unknown
END
) IN (#Compliant)
/* Perform cleanup */
IF OBJECT_ID('tempdb..#MaintenanceInfo', 'U') IS NOT NULL
DROP TABLE #MaintenanceInfo;
/* #endregion */
/*##=============================================*/
/*## END QUERY BODY */
/*##=============================================*/
`
Is there an easy way to achieve this?
I have tried to look at the official Microsoft documentation but are still not able to convert the query to a view. https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
As I am new to SQL language I am not sure where to start.
So I agree with Larnu, that this probably doesn't make a ton of sense. But there are cases where one might want to be able to run multiple batches of queries / procedural code from an object that's as consumable as a view. I've done this once in a case where I needed to maximize my options for performance tuning without losing the consumability of the object. So for the sake of when it does make sense, this is something you could do:
Wrap your code in a stored procedure.
Use OPENQUERY() to call your procedure.
Wrap the OPENQUERY() call in a view.
Limitations with this methodology is it's rather static:
You can't pass parameters to your stored procedure
If you use temp tables in your stored procedure, then you need to use the WITH RESULT SETS clause to explicitly define the shape of your result set
The procedure can only return one result set
The SQL Server Engine puts a hard-coded cardinality estimate of 10,000 against OPENQUERY(). So in cases where your procedure returns a lot more rows (typically an order of magnitude or more) than 10,000, e.g. 1 million rows, then you may experience some performance issues with joining the wrapper view to other objects.
Example:
-- Step 1: Wrap the procedural code in a stored procedure
CREATE PROCEDURE dbo.RunSomeCode
AS
BEGIN
CREATE TABLE #Results (ID INT, SomeValue VARCHAR(100));
DECLARE #SomeVariable INT = 0;
WHILE (#SomeVariable < 5)
BEGIN
SET #SomeVariable = #SomeVariable + 1;
INSERT INTO #Results (ID, SomeValue)
SELECT ID, SomeValue
FROM SomeTable
WHERE ID = #SomeVariable
END
SELECT ID, SomeValue
FROM #Results;
END
GO
-- Step 2 & 3: Wrap an OPENQUERY() call to the procedure in a view.
CREATE VIEW dbo.SomeView
AS
SELECT ID, SomeValue
FROM OPENQUERY
(
'
LocalServerName,
EXEC dbo.RunSomeCode
WITH RESULT SETS
((
ID INT,
SomeValue VARCHAR(100)
))
'
);
Voila, you can now execute the procedure by SELECTing from the view:
SELECT ID, SomeValue
FROM dbo.SomeView;

Stored procedue issue with AND statement when checking is null

I can't work out why my value is being ignored.
In my stored procedure it has these two AND statements
AND (#Current IS NULL OR (o.[OrderStatusId] <> 40) AND (o.[OrderStatusId] <> 30) AND ( NOT ((o.[ShippingStatusId] IN (30, 40)) AND (o.[PaymentStatusId] IN (30, 35, 40)))))
AND (#Printed IS NULL OR o.[Printed] = #Printed)
The #Printed value is a bit same as #Current, and is passed through to the stored procedure just the same as #Current
But the printed value doesn't pull results, it's like it's doing nothing although I know the results should vary.
I'm converting a linq query to the stored procedure, so I know the results should differ.
Here is the part of the linq query which is used.
if (current.HasValue && current.Value)
query = query.Where(o => o.OrderStatusId != (int)OrderStatus.Cancelled && o.OrderStatusId != (int)OrderStatus.Complete && !((o.ShippingStatusId == (int)ShippingStatus.Shipped || o.ShippingStatusId == (int)ShippingStatus.Delivered) && o.Printed && (o.PaymentStatusId == (int)PaymentStatus.Paid || o.PaymentStatusId == (int)PaymentStatus.PartiallyRefunded || o.PaymentStatusId == (int)PaymentStatus.Refunded)));
if (printed.HasValue)
query = query.Where(o => printed.Value == o.Printed);
Any ideas
UPDATE:
Looking at the query from linq in vs debugger I can see the following query, but I' no db expert so I'm a little lost looking at this one.
{SELECT
[Project2].[Id] AS [Id],
[Project2].[OrderGuid] AS [OrderGuid],
[Project2].[StoreId] AS [StoreId],
[Project2].[CustomerId] AS [CustomerId],
[Project2].[BillingAddressId] AS [BillingAddressId],
[Project2].[ShippingAddressId] AS [ShippingAddressId],
[Project2].[PickUpInStore] AS [PickUpInStore],
[Project2].[OrderStatusId] AS [OrderStatusId],
[Project2].[ShippingStatusId] AS [ShippingStatusId],
[Project2].[PaymentStatusId] AS [PaymentStatusId],
[Project2].[PaymentMethodSystemName] AS [PaymentMethodSystemName],
[Project2].[CustomerCurrencyCode] AS [CustomerCurrencyCode],
[Project2].[CurrencyRate] AS [CurrencyRate],
[Project2].[CustomerTaxDisplayTypeId] AS [CustomerTaxDisplayTypeId],
[Project2].[VatNumber] AS [VatNumber],
[Project2].[OrderSubtotalInclTax] AS [OrderSubtotalInclTax],
[Project2].[OrderSubtotalExclTax] AS [OrderSubtotalExclTax],
[Project2].[OrderSubTotalDiscountInclTax] AS [OrderSubTotalDiscountInclTax],
[Project2].[OrderSubTotalDiscountExclTax] AS [OrderSubTotalDiscountExclTax],
[Project2].[OrderShippingInclTax] AS [OrderShippingInclTax],
[Project2].[OrderShippingExclTax] AS [OrderShippingExclTax],
[Project2].[PaymentMethodAdditionalFeeInclTax] AS [PaymentMethodAdditionalFeeInclTax],
[Project2].[PaymentMethodAdditionalFeeExclTax] AS [PaymentMethodAdditionalFeeExclTax],
[Project2].[TaxRates] AS [TaxRates],
[Project2].[OrderTax] AS [OrderTax],
[Project2].[OrderDiscount] AS [OrderDiscount],
[Project2].[OrderTotal] AS [OrderTotal],
[Project2].[RefundedAmount] AS [RefundedAmount],
[Project2].[RewardPointsWereAdded] AS [RewardPointsWereAdded],
[Project2].[CheckoutAttributeDescription] AS [CheckoutAttributeDescription],
[Project2].[CheckoutAttributesXml] AS [CheckoutAttributesXml],
[Project2].[CustomerLanguageId] AS [CustomerLanguageId],
[Project2].[AffiliateId] AS [AffiliateId],
[Project2].[CustomerIp] AS [CustomerIp],
[Project2].[AllowStoringCreditCardNumber] AS [AllowStoringCreditCardNumber],
[Project2].[CardType] AS [CardType],
[Project2].[CardName] AS [CardName],
[Project2].[CardNumber] AS [CardNumber],
[Project2].[MaskedCreditCardNumber] AS [MaskedCreditCardNumber],
[Project2].[CardCvv2] AS [CardCvv2],
[Project2].[CardExpirationMonth] AS [CardExpirationMonth],
[Project2].[CardExpirationYear] AS [CardExpirationYear],
[Project2].[AuthorizationTransactionId] AS [AuthorizationTransactionId],
[Project2].[AuthorizationTransactionCode] AS [AuthorizationTransactionCode],
[Project2].[AuthorizationTransactionResult] AS [AuthorizationTransactionResult],
[Project2].[CaptureTransactionId] AS [CaptureTransactionId],
[Project2].[CaptureTransactionResult] AS [CaptureTransactionResult],
[Project2].[SubscriptionTransactionId] AS [SubscriptionTransactionId],
[Project2].[PaidDateUtc] AS [PaidDateUtc],
[Project2].[ShippingMethod] AS [ShippingMethod],
[Project2].[Printed] AS [Printed],
[Project2].[PrintedOnUtc] AS [PrintedOnUtc],
[Project2].[IsSupport] AS [IsSupport],
[Project2].[EditedStatusId] AS [EditedStatusId],
[Project2].[Deleted] AS [Deleted],
[Project2].[Id1] AS [Id1]
FROM ( SELECT
CASE WHEN (([Extent1].[Printed] <> 1) AND (N'Express Delivery' = [Extent1].[ShippingMethod])) THEN N'1' ELSE N'0' END AS [C1],
CASE WHEN ([Extent1].[Printed] <> 1) THEN CASE WHEN (([Extent1].[ShippingMethod] IN (N'Fast Delivery',N'My Point Pickup')) AND ( NOT EXISTS (SELECT
1 AS [C1]
FROM [dbo].[GenericAttribute] AS [Extent3]
WHERE (N'WarehouseOverride' = [Extent3].[Key]) AND (N'Order' = [Extent3].[KeyGroup]) AND ([Extent3].[EntityId] = [Extent1].[Id])
))) THEN N'0' ELSE N'1' END ELSE N'0' END AS [C2],
[Extent1].[Id] AS [Id],
[Extent1].[OrderGuid] AS [OrderGuid],
[Extent1].[StoreId] AS [StoreId],
[Extent1].[CustomerId] AS [CustomerId],
[Extent1].[BillingAddressId] AS [BillingAddressId],
[Extent1].[ShippingAddressId] AS [ShippingAddressId],
[Extent1].[PickUpInStore] AS [PickUpInStore],
[Extent1].[OrderStatusId] AS [OrderStatusId],
[Extent1].[ShippingStatusId] AS [ShippingStatusId],
[Extent1].[PaymentStatusId] AS [PaymentStatusId],
[Extent1].[PaymentMethodSystemName] AS [PaymentMethodSystemName],
[Extent1].[CustomerCurrencyCode] AS [CustomerCurrencyCode],
[Extent1].[CurrencyRate] AS [CurrencyRate],
[Extent1].[CustomerTaxDisplayTypeId] AS [CustomerTaxDisplayTypeId],
[Extent1].[VatNumber] AS [VatNumber],
[Extent1].[OrderSubtotalInclTax] AS [OrderSubtotalInclTax],
[Extent1].[OrderSubtotalExclTax] AS [OrderSubtotalExclTax],
[Extent1].[OrderSubTotalDiscountInclTax] AS [OrderSubTotalDiscountInclTax],
[Extent1].[OrderSubTotalDiscountExclTax] AS [OrderSubTotalDiscountExclTax],
[Extent1].[OrderShippingInclTax] AS [OrderShippingInclTax],
[Extent1].[OrderShippingExclTax] AS [OrderShippingExclTax],
[Extent1].[PaymentMethodAdditionalFeeInclTax] AS [PaymentMethodAdditionalFeeInclTax],
[Extent1].[PaymentMethodAdditionalFeeExclTax] AS [PaymentMethodAdditionalFeeExclTax],
[Extent1].[TaxRates] AS [TaxRates],
[Extent1].[OrderTax] AS [OrderTax],
[Extent1].[OrderDiscount] AS [OrderDiscount],
[Extent1].[OrderTotal] AS [OrderTotal],
[Extent1].[RefundedAmount] AS [RefundedAmount],
[Extent1].[RewardPointsWereAdded] AS [RewardPointsWereAdded],
[Extent1].[CheckoutAttributeDescription] AS [CheckoutAttributeDescription],
[Extent1].[CheckoutAttributesXml] AS [CheckoutAttributesXml],
[Extent1].[CustomerLanguageId] AS [CustomerLanguageId],
[Extent1].[AffiliateId] AS [AffiliateId],
[Extent1].[CustomerIp] AS [CustomerIp],
[Extent1].[AllowStoringCreditCardNumber] AS [AllowStoringCreditCardNumber],
[Extent1].[CardType] AS [CardType],
[Extent1].[CardName] AS [CardName],
[Extent1].[CardNumber] AS [CardNumber],
[Extent1].[MaskedCreditCardNumber] AS [MaskedCreditCardNumber],
[Extent1].[CardCvv2] AS [CardCvv2],
[Extent1].[CardExpirationMonth] AS [CardExpirationMonth],
[Extent1].[CardExpirationYear] AS [CardExpirationYear],
[Extent1].[AuthorizationTransactionId] AS [AuthorizationTransactionId],
[Extent1].[AuthorizationTransactionCode] AS [AuthorizationTransactionCode],
[Extent1].[AuthorizationTransactionResult] AS [AuthorizationTransactionResult],
[Extent1].[CaptureTransactionId] AS [CaptureTransactionId],
[Extent1].[CaptureTransactionResult] AS [CaptureTransactionResult],
[Extent1].[SubscriptionTransactionId] AS [SubscriptionTransactionId],
[Extent1].[PaidDateUtc] AS [PaidDateUtc],
[Extent1].[ShippingMethod] AS [ShippingMethod],
[Extent1].[Printed] AS [Printed],
[Extent1].[PrintedOnUtc] AS [PrintedOnUtc],
[Extent1].[IsSupport] AS [IsSupport],
[Extent1].[EditedStatusId] AS [EditedStatusId],
[Extent1].[Deleted] AS [Deleted],
[Extent2].[Id] AS [Id1]
FROM [dbo].[Order] AS [Extent1]
LEFT OUTER JOIN [dbo].[RewardPointsHistory] AS [Extent2] ON ([Extent2].[UsedWithOrder_Id] IS NOT NULL) AND ([Extent1].[Id] = [Extent2].[UsedWithOrder_Id])
WHERE ([Extent1].[Deleted] <> 1) AND (40 <> [Extent1].[OrderStatusId]) AND (30 <> [Extent1].[OrderStatusId]) AND ( NOT (([Extent1].[ShippingStatusId] IN (30,40)) AND ([Extent1].[Printed] = 1) AND ([Extent1].[PaymentStatusId] IN (30,35,40))))
) AS [Project2]
ORDER BY [Project2].[C1] DESC, [Project2].[Printed] ASC, [Project2].[C2] DESC, [Project2].[CreatedOnUtc] DESC}
Here is my stored procedure for you to look at:
USE [Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[OrderLoad]
-- Add the parameters for the stored procedure here
#OrderId int = null,
#CustomerId int = null,
#WarehouseId int = null,
#BillingCountryId int = null,
#PaymentMethodSystemName nvarchar(max) = null,
#OrderStatusId int = null,
#PaymentStatusId int = null,
#ShippingStatusId int = null,
#BillingEmail nvarchar(max) = null,
#BillingFirstName nvarchar(max) = null,
#BillingLastName nvarchar(max) = null,
#PurchasedPreviously bit = null,
#Printed bit = null,
#OrderNotes nvarchar(max) = null,
#ZendeskId nvarchar(max) = null,
#RexCode nvarchar(max) = null,
#Current bit = null,
#Challenge bit = null,
#ShippingMethod nvarchar(max) = null,
#EditedStatus int = null,
#OrderGuid nvarchar(max) = null,
#SupportReason int = null,
#CreatedFromUtc datetime = null,
#CreatedToUtc datetime = null,
#IsSupport bit = null,
#PageIndex int = 0,
#PageSize int = 2147483644,
#TotalRecords int = null OUTPUT
AS
BEGIN
DECLARE
#sql nvarchar(max)
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
create table #TempTotal (RowNum int identity(1,1), id int);
--select all
INSERT INTO #TempTotal ([id])
SELECT o.[Id]
FROM [Test].[dbo].[Order] o with (NOLOCK)
-- Another alternative to bypass left join, which works with pagination
LEFT join [Test].[dbo].[Address] a on a.Id = o.BillingAddressId and (
coalesce(#BillingEmail,'') <> ''
or coalesce(#BillingFirstName,'') <> ''
or coalesce(#BillingLastName,'') <> ''
or coalesce(#BillingCountryId,'') <> ''
)
WHERE
o.[Deleted] = 0
/*AND (#BillingEmail IS null OR a.[Email] LIKE '%' + #BillingEmail + '%')
AND (#BillingFirstName IS null OR a.[FirstName] LIKE '%' + #BillingFirstName + '%')
AND (#BillingLastName IS null OR a.[LastName] LIKE '%' + #BillingLastName + '%')
AND (#BillingCountryId IS null OR a.[CountryId] = #BillingCountryId)
*/
AND (#Printed IS NULL OR o.[Printed] = #Printed)
AND (#Current IS NULL OR (o.[OrderStatusId] <> 40) AND (o.[OrderStatusId] <> 30) AND ( NOT ((o.[ShippingStatusId] IN (30, 40)) /*AND (o.[Printed] = '1')*/ AND (o.[PaymentStatusId] IN (30, 35, 40)))))
AND (#IsSupport IS null OR o.[IsSupport] = #IsSupport)
--paging
DECLARE #PageLowerBound int
SET #PageLowerBound = #PageSize * #PageIndex
-- Return the paged records
select [Id] --note select * can produce unexpected results
,[OrderGuid]
,[RexOrderId]
,[StoreId]
,[CustomerId]
,[BillingAddressId]
,[ShippingAddressId]
,[PickUpInStore]
,[OrderStatusId]
,[ShippingStatusId]
,[PaymentStatusId]
,[PaymentMethodSystemName]
,[CustomerCurrencyCode]
,[CurrencyRate]
,[CustomerTaxDisplayTypeId]
,[VatNumber]
,[OrderSubtotalInclTax]
,[OrderSubtotalExclTax]
,[OrderSubTotalDiscountInclTax]
,[OrderSubTotalDiscountExclTax]
,[OrderShippingInclTax]
,[OrderShippingExclTax]
,[PaymentMethodAdditionalFeeInclTax]
,[PaymentMethodAdditionalFeeExclTax]
,[TaxRates]
,[OrderTax]
,[OrderDiscount]
,[OrderTotal]
,[RefundedAmount]
,[RewardPointsWereAdded]
,[CheckoutAttributeDescription]
,[CheckoutAttributesXml]
,[CustomerLanguageId]
,[AffiliateId]
,[CustomerIp]
,[AllowStoringCreditCardNumber]
,[CardType]
,[CardName]
,[CardNumber]
,[MaskedCreditCardNumber]
,[CardCvv2]
,[CardExpirationMonth]
,[CardExpirationYear]
,[AuthorizationTransactionId]
,[AuthorizationTransactionCode]
,[AuthorizationTransactionResult]
,[CaptureTransactionId]
,[CaptureTransactionResult]
,[SubscriptionTransactionId]
,[PaidDateUtc]
,[ShippingMethod]
,[Printed]
,[Deleted]
,[CreatedOnUtc]
,[EditedStatusId]
,[IsSupport]
,[PrintedOnUtc]
from [Test].[dbo].[Order] ord with (NOLOCK)
where ord.[Id] in (
select id
from #TempTotal tt
)
ORDER BY
(CASE #IsSupport
WHEN 0 THEN ord.[Printed]
END) ASC
, (CASE #IsSupport
WHEN 0 THEN ord.[CreatedOnUtc]
END) DESC
, (CASE #IsSupport
WHEN 1 THEN ord.[CreatedOnUtc]
END) DESC
--ORDER BY ord.[CreatedOnUtc] DESC
OFFSET #PageLowerBound ROWS FETCH NEXT #PageSize ROWS ONLY;
--total records
select #TotalRecords = count(*) from #TempTotal;
DROP TABLE #TempTotal
END

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, search for true, false or both

I am currently trying to code an SQL search that can return TRUE, FALSE, or NEITHER. While the code I currently have works, I do not like the fact that I had to copy and paste a lot of code, and was wondering if there was a way to reduce the amount of code here.
DECLARE #FYear int = 2017
DECLARE #FQuarter char(2) = 'Q2'
DECLARE #FINANCIAL_GOAL_MET bit = NULL
IF(#FINANCIAL_GOAL_MET IS NULL)
SELECT FYear,
FQuarter,
IIF(FINANCIAL_GOAL_MET = 'TRUE', 1,0) AS Financial_Goal_Met
FROM Finances
WHERE (FYear = #FYear)
AND (FQuarter = #FQuarter)
ELSE
SELECT FYear,
FQuarter,
IIF(FINANCIAL_GOAL_MET = 'TRUE', 1,0) AS Financial_Goal_Met
FROM Finances
WHERE (FYear = #FYear)
AND (FQuarter = #FQuarter)
AND FINANCIAL_GOAL_MET = #FINANCIAL_GOAL_MET
You can do this in one query:
DECLARE #FYear int = 2017;
DECLARE #FQuarter char(2) = 'Q2';
DECLARE #FINANCIAL_GOAL_MET bit = NULL;
SELECT FYear, FQuarter,
(CASE WHEN FINANCIAL_GOAL_MET = 'TRUE' THEN 1 ELSE 0
END) AS Financial_Goal_Met
FROM Finances f
WHERE (FYear = #FYear) AND (FQuarter = #FQuarter) AND
(#FINANCIAL_GOAL_MET IS NULL OR FINANCIAL_GOAL_MET = #FINANCIAL_GOAL_MET);
For those not familiar with the bit type in SQL Server, 'TRUE' is accepted for comparison, even though it is a string.

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

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.