Severe error on MERGE OUTPUT statement - sql-server-2008

I'm getting a severe error - code 20, from a Merge statement and I am not sure why. The MERGE runs fine if I remove the OUTPUT $action clause, and updates/inserts the target table as expected. As soon as I put the OUTPUT clause in, either as a simple OUTPUT $action or storing it in a table variable and selecting from that, it causes an error level 20. I am using two CTEs for the target and source. Not sure if that's contributing to the issue, but as I said, it works fine without an OUTPUT clause. Using SQL Server 2008. I've removed most of the columns for readability here.
USE [DM]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[MergeMDATEST]
#InsertAuditKey INT = 10
,#UpdateAuditKey INT = 1
AS
SET NOCOUNT ON;
DECLARE #RowCounts TABLE (mergeAction varchar(20));
--------------------------------------------
--- CTEs to add in Binary_Checksum Calcs ---
WITH SourceQuery AS
(
SELECT TOP 100
[Company]
,[AccountNumber]
,BINARY_CHECKSUM([Company]) As [Checksum]
FROM #temptestMergeSource
)
,TargetTable AS
(
SELECT TOP 100
[Company]
,BINARY_CHECKSUM([Company]) As [Checksum]
FROM #temptestMergeTarget
)
MERGE TargetTable AS Target
USING SourceQuery As Source
ON (
Target.[AccountIndex] = Source.[AccountIndex]
AND Target.[CodeID] = Source.[CodeID]
AND Target.[GroupID] = Source.[GroupID]
)
WHEN MATCHED AND (Target.[Checksum] <> Source.[Checksum]) THEN
UPDATE SET
[AccountNumber] = Source.[AccountNumber]
,[AuditKey] = #UpdateAuditKey
WHEN NOT MATCHED THEN
INSERT (
[Company]
,[AuditKey]
)
VALUES (
Source.[Company]
,#InsertAuditKey
)
OUTPUT $action INTO #RowCounts;
SELECT * FROM #RowCounts
-----RowCounts returned for auditing
--SELECT
-- COUNT(CASE WHEN mergeAction = 'Insert' THEN 1 ELSE 0 END) As [INSERT]
-- ,COUNT(CASE WHEN mergeAction = 'Update' THEN 1 ELSE 0 END) As [UPDATE]
--FROM #RowCounts

A calculated column in a CTE Target combined with an output clause results in a fatal error. Bug submission on Microsoft Connect

Related

Why does a MySql query, valid in Workbench, return syntax errors in phpmyadmin?

so i have 2 tables as table1 and table2 in 2 different databases as id_information and id_information_backup. Both the tables have the following columns: (id bigint, name varchar, surname varchar) I made this trigger where when the user enters name and surname in table1 , it calculates the ascii code of it and do some calculations and store it in the "name" column of the second table which is "table2". All of these has been done in Mysql workbench. when i import the code into phpmyadmin then it gives me too many syntax errors. I tried to figure what syntax errors do i have but i could not find. I am sharing the trigger below. Kindly help me if you can. I will really appreciate it. I guess it is because of the version that i used is MySQL workbench 8.0 and the version that i am importing this into is PHPmyadmin 4.9.4 . Fix the problem if you can please.
delimiter $$
CREATE DEFINER = CURRENT_USER TRIGGER `id_information`.`table1_after_INSERT1` AFTER INSERT ON `table1` FOR EACH ROW
BEGIN
declare p , r , copy, result, result1 decimal(64,0);
declare name1, surnam varchar(15);
declare a int;
set name1 = new.name;
set surnam = new.surname;
set a= 100;
set result =0;
set copy = 0;
set result1 =0;
set p =0 ;
set r =0 ;
with recursive cte as (
select name1 as name1, left(name1, 1) as val, 1 as idx
union all
select name1, substring(name1, idx + 1, 1), idx + 1
from cte
where idx < char_length(name1)
)
select group_concat(ascii(val) + a order by idx separator '') ascii_word from cte into result;
with recursive ctee as (
select surnam as surnam, left(surnam, 1) as vall , 1 as idxx
union all
select surnam, substring(surnam, idxx+ 1, 1), idxx+ 1
from ctee
where idxx< char_length(surnam)
)
select group_concat(ascii(vall ) + a order by idxx separator '') ascii_word from ctee into result1;
select group_concat(result, result1) into copy;
insert into id_information_backup.table2 set table2.name = copy;
END$$
delimiter ;
When you try to run the command (by pressing the "Go" button at the bottom of the SQL text area), what happens?
If phpMyAdmin is showing the errors as red circles with a white x to the left of the SQL area before submitting, then these are syntax warnings that won't affect your ability to submit the query. These are provided as hints by the SQL linter in phpMyAdmin.
phpMyAdmin syntax warning:
If the errors come after submitting the statements, then the errors come from MySQL itself and aren't directly caused by phpMyAdmin.
MySQL syntax error:
In PHPMyAdmin you need to set up delimiter in a small box under the main query
It should be signed as "Delimiter" ;-)
I ended getting caught by that one a few time :-D

mysql test IF variable IS NULL (or empty)

we are selecting a row in mysql/mariadb and storing chosen columns in variables. After this, using IF we would like to test one of the variables and see if it has been set or is null, if it is then we assign it a value and continue on.
Using IS NULL does not seem to work on a non expression.
select id,history,active,jsonorder
INTO #id,#history,#active,#jsonorder
from myTable where uid = myUid
delimiter |
IF #jsonorder IS NULL THEN
#myNewVal="zzz";
ELSE
#myNewVal="yyy";
END IF|
insert into otherTable (colA) VALUES (#myNewVar);
What is the correct way to test if the select has provided a value into a variable such as #jsonorder?
We could use an expression in the SELECT list:
SELECT t.id
, t.history
, t.active
, IFNULL(t.order,1) AS `order`
INTO #id
, #history
, #active
, #order
FROM `myTable` t
WHERE t.uid = ...
Note that DELIMITER is not a SQL statement; it's command recognized by the mysql command line client (and some other clients).
documented here in MySQL Reference Manual: https://dev.mysql.com/doc/refman/8.0/en/mysql-commands.html
It's not clear in what context this script is being run; is this part of a MySQL stored program, or being called application code. What we are actually trying to achieve?
There are several other expressions we could use in the SELECT list, e.g.
CASE WHEN t.order IS NULL THEN 1 ELSE t.order END`
or
IF(t.order IS NULL,1,t.order)
et al.
FOLLOWUP
If we don't want to modify the original SQL statement; if we execute this:
SELECT t.id
, t.history
, t.active
, t.jsonorder
INTO #id
, #history
, #active
, #jsonorder
FROM `myTable` t
WHERE t.uid = ...
And then we want to perform an assignment to another user defined variable, based on a conditional test, we can achieve that in another SELECT or a SET statement.
For example:
SELECT #myNewVal := IF(#jsonorder IS NULL,'zzz','yyy') ;
ELSE 'yyy'
-or-
SELECT CASE
WHEN #jsonorder IS NULL
THEN 'zzz'
ELSE 'yyy'
END
INTO #myNewVal
-or-
SET #myNewVal := IF(#jsonorder IS NULL,'zzz','yyy')
The IF statement can only be used in Stored Routines. The IF function can be used virtually anywhere an expression can be put:
select id,history,active,jsonorder
INTO #id,#history,#active,#jsonorder
from myTable
where uid = myUid;
insert into otherTable (colA)
VALUES (IF(#jsonorder IS NULL, "zzz", "yyy"));
Where does myUid come from?
Is otherTable only one column wide? Or do all the other columns have defaults?
(I'm worried that you over-sanitized the question.)
This solve for cases where order is null, but not for when myUid doesnt exist in your table
SELECT id,history,active, COALESCE(order,1)
INTO #id,#history,#active,#order
FROM myTable
WHERE uid = myUid

SSRS issue with using dynamic fields in SP

I have a SP like this:
ALTER PROCEDURE [dbo].[ReportGateWay]
(
#ISO bigint= 0,
#Gateway bigint= 0
)
AS
BEGIN
DECLARE #SQL nvarchar(max)
SET #SQL= 'SELECT * FROM
(
SELECT DISTINCT I.DBAName [ISOName], BG.GatewayName
FROM Iso I
LEFT OUTER JOIN BusinessGateway BG
ON I.GatewayName = BG.MerchantBusinessGatewayId AND I.IsActive = 1 and BG.IsActive = 1
WHERE ('+CAST(#ISO AS varchar(10))+' = 0 OR I.IsoId = '+ CAST(#ISO AS varchar(10)) +')
AND ('+CAST(#Gateway AS varchar(10))+' = 0 OR BG.MerchantBusinessGatewayId = '+ CAST(#Gateway AS varchar(10)) +')
) AS tb1
PIVOT
(
Count(GatewayName) for GatewayName in ('+ SUBSTRING((SELECT ',[' + BG.GatewayName + ']' FROM BusinessGateway BG
WHERE #Gateway = 0 OR BG.MerchantBusinessGatewayId = #Gateway
FOR XML PATH('')), 2, 200000 ) + ')
) AS pvt
ORDER BY pvt.ISOName'
EXECUTE (#SQL)
END
I need to invoke this in SSRS. The problem is that when on creating dataset for this, I get an error which read:
You must have atleast one field for your dataset
What can be done in this case?
You have this error message because SSRS cannot infer your schema from the query.
You could declare manually your fields in DataSet Properties => Fields:
Field Name, Field Source
ISOName, ISOName
Gateway1, Gateway1
Gateway2, Gateway2
EDIT
If you really want to have dynamic columns and can't define static column names, you could try a trick like this.
The idea is to create a function returning an Arraylist containing Column headers and values.
Why are you not executing the Procedure by creating a dataset of query type "Stored Procedure"?
By doing this you will be able to see the fields getting returned from the SP in your dataset.
You can also pass the parameter values to the SP by creating the report parameters.
Edit:
How to pass parameter to SP in SSRS:
Say you have sp as below:
create procedure [dbo].[TestProcpk] #value varchar(20)
as
select * from testProc where value = #value
You have to create parameters with same name as above i.e. #value.
I have below data in testProc:
ID|Value
1|xxx
2|yyy
3|zzz
If I run the report with parameter value of xxx, I will get 1|xxx only.
Also, You don't have to specify anything after selecting the SP from drop down.
How you are not able to pass param value to SP?

MySQL procedure gone wrong

I have a MySQL database in which I have the following rows (by exemple) created by default (id, task and case may be different but the current value is always 1)
....idtaskcaseuser............datecurrent
238......31001.....0..............null..........1
239......41001.....0..............null..........1
I have to randomly create rows like this with insert statement (new rows). As you can see a date is filled and de current equal 0
....idtaskcaseuser............datecurrent
240......51001.....12015.04.03..........0
241......21002.....12015.04.03..........0
When I come across one of the lines created by default I want to use an update instead of an insert statement.
So I created the following procedure in MySQL
DELIMITER //
DROP PROCEDURE IF EXISTS FillProgress//
CREATE PROCEDURE FillProgress ( get_case INT(10),get_task INT(10), get_user INT(10) )
BEGIN
DECLARE test tinyint(1);
SET test = (SELECT COUNT(*) FROM progress WHERE case_id = get_case AND task_id = get_task);
IF test = 1 THEN
UPDATE progress SET current = 0, date = NOW(), user_id = get_user WHERE task_id = get_id AND case_id = get_case;
ELSE
INSERT INTO progress(task_id,case_id,user_id,date,current) VALUES (get_task,get_case,get_user,NOW(),0);
END IF;
END; //
DELIMITER ;
I use count to see if a already have a row with the same case and task. If it's true (test=1) I use UPDATE, otherwise and use INSERT.
If I test with the following row already wrote in the database
....idtaskcaseuserdatecurrent
241......41001.....0..null..........1
I use CALL FillProgress(1001,4,1);
The row is not updated, but I do not have any error message.
11:38:02 CALL FillProgress(1001,4,1) 0 row(s) affected 0.000 sec
And if I manually use my update query
UPDATE progress SET current = 0, date = NOW(), user_id = 1 WHERE task_id = 4 AND case_id = 1001;
It works like a charm.
The insert query also works fine.
The UPDATE query within the procedure has a "WHERE task_id = get_id" clause, however I don't see get_id being defined in the procedure; there is a "get_task" parameter for the stored procedure, though.

EXECUTESQL error

Here is the following piece of code that I am trying to execute on SQL Server.
DECLARE #string NVARCHAR(MAX) = '
CREATE PROC [dbo].[Trend]
#slsID NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON
DECLARE #BeginningRange varchar(20),
#EndingRange varchar(20)
SET #EndingRange = ''12*13''
SET #BeginningRange = ''12*02''
;WITH CTE1 AS(
SELECT
dbo.Field1,dbo.Field2,dbo.Field3
FROM dbo.Table1 join dbo.Table2 where...conditions
weekNum BETWEEN (#BeginningRange) AND (#EndingRange)
)
SELECT * FROM CTE1
UNPIVOT
( numbers for type in (Field1, Field2, Field3, Field4)
) as p PIVOT
(
Sum(numbers) for
WeekNum in ([12*02],[12*03],[12*04],[12*05],[12*06],[12*07],[12*08],[12*09],[12*10], [12*11],[12*12],[12*13])
) as q
END
'
EXECUTE SP_EXECUTESQL #STRING
When I try to run this, it errors out saying that
"Incorrect syntax near the keywor 'as'"
I took this code out and executed it separately and it didn't error out. Am I missing something here?
Look like missing parentheses around the parameter to the procedure.
One trick you can use is the print out the sql statement and then try to run that - the error message might give you more info
print #STRING
PIVOT and UNPIVOT clauses each require two closing parentheses.
UNPIVOT (... FOR ... IN (...) ) AS ...
PIVOT (... FOR ... IN (...) ) AS ...
where...conditions
This won't pass a syntax check. If you have removed the actual conditions it may be that this is where your error is. And:
dbo.Table1 join dbo.Table2
has no ON clause
I saw both of these by doing a syntax check on the results of print #string which is the first step you should have taken to find the issue. I still say that based on what you gave us there is no reason at all to use dynamic SQl and it is a poor practice to use dynamic SQL if you don't need it.