Query Result export per email - delimiter

I Try to export the Query result per E-Mail as Attach
here the code:
DECLARE #Delimiter Char(1)
SET #Delimiter = CHAR(9)
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'MyProfile',
#recipients = 'myemailaad#mail.com',
#subject = 'Defects Total Value',
#body='MyText',
#query= 'MyQuery',
#attach_query_result_as_file=1,
#query_result_no_padding=1,
#Query_Result_Header = 1,
#query_attachment_filename = 'Results.xls',
#query_result_separator =#Delimiter
it work normally but I have two issues:
The second row is empty : how deletet it(in the query)?
In the Query i use : SET NOCOUNT ON,
but in the xls file I can see the count (see screenshot),
how deletet it(in the query)?
Thanks in advance
[[1]: https://i.stack.imgur.com/QPZlL.png][1]

the second issue is solved :no count in the result
the "set NOCOUNT on; must be in the query and not only in the stored procedure.
#Query='set NOCOUNT on;select....'
if the "SET NOCOUNT ON;" is only in the Sp like this:
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
it isn't enough to not returned the count

Related

Getting the rowsAffected output in log analytics

I'm trying to get the rows affected output from an sql server stored procedure activity in azure data factory to azure log analytics. I can currently get the rowsCopied and rowsRead from the copy activity. Would appreciate any help.
Below is the sample code in determining the effected rows from stored procedure in SQL server
CREATE PROCEDURE UpdateTables
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #RowCount1 INTEGER
DECLARE #RowCount2 INTEGER
DECLARE #RowCount3 INTEGER
DECLARE #RowCount4 INTEGER
UPDATE Table1 Set Column = 0 WHERE Column IS NULL
SELECT #RowCount1 = ##ROWCOUNT
UPDATE Table2 Set Column = 0 WHERE Column IS NULL
SELECT #RowCount2 = ##ROWCOUNT
UPDATE Table3 Set Column = 0 WHERE Column IS NULL
SELECT #RowCount3 = ##ROWCOUNT
UPDATE Table4 Set Column = 0 WHERE Column IS NULL
SELECT #RowCount4 = ##ROWCOUNT
SELECT #RowCount1 AS Table1, #RowCount2 AS Table2, #RowCount3 AS Table3, #RowCount4 AS Table4
END
Go through this SO for complete details

SQL Server 2017 Stored Procedure wants table variable declared but it already exists

Been a while since I have done any sereious T-SQL. I thought I had this right but I am receiving an error that I cannot figure out the cause of. This is for a stored procedure that is not complex. The code is below:
--======================================================
-- Create Natively Compiled Stored Procedure Template
--======================================================
USE Viper;
GO
-- Drop stored procedure if it already exists
IF OBJECT_ID('API.newCategory','P') IS NOT NULL
DROP PROCEDURE API.newCategory;
GO
CREATE PROCEDURE API.newCategory
-- Add the parameters for the stored procedure here
#Category varchar(20) = null
WITH NATIVE_COMPILATION, SCHEMABINDING
AS BEGIN ATOMIC WITH
(
TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
)
--Insert statements for the stored procedure here
DECLARE #tmp int = 0;
IF #Category IS NOT NULL
AND #Category != ''
SET #tmp = ISNULL(
(SELECT idCategory
FROM Products.Category
WHERE Category = #Category),0);
IF #tmp = 0
INSERT INTO Products.Category (Category)
OUTPUT inserted.idCategory INTO #tmp
VALUES (#Category);
ELSE
UPDATE Category
SET active = 1
WHERE idCategory = #tmp;
RETURN #tmp;
END;
GO
The error message that I am receiving is:
Msg 1087, Level 16, State 1, Procedure newCategory, Line 22 [Batch
Start Line 11]
Must declare the table variable "#tmp".
I hope someone can point me in the right direction. I am sure that it is something stupidly simple, I just can't see it right now. A bit rusty I'm afraid.
Just to be clear, the operational goal of the SP is to:
1/ Check that there is actually a Category supplied to work with
2/ If there is then try and get its primary key id (idCategory)
3/ If there is no PK for the Category then insert it and return the idCategory into #tmp
4/ If there is a PK then make sure the active column is set to 1
5/ return #tmp as the result (either the PK or 0)
Cheers and thanks for any help
The Frog
Your problem is in this statement:
IF #tmp = 0
INSERT INTO Products.Category (Category)
OUTPUT inserted.idCategory INTO #tmp
VALUES (#Category);
You are doing an OUTPUT INTO where what you are output into your previously declare #tmp which is declared as an int. OUTPUT statements can only be against tables, temp tables or table variables.
A workaround could be to declare a table variable #catTab: DECLARE #catTab AS TABLE(CatID int) and OUTPUT into that variable followed by a: SELECT #tmp = CatID FROM #catTab. That should do it.

Creating stored procedure using cfstoredproc

Is is possible to create a stored procedure using cfstoredproc? When I run the following I get Incorrect syntax near 'GO'.
<cffile action="read" file="mypath/myFile.sql" variable="sp_1">
<cfstoredproc procedure="sp_executesql" dataSource="#getDatasource()#">
<cfprocparam type="in" cfsqltype = "cf_sql_varchar" value ='#sp_1#'>
</cfstoredproc>
myFile.sql
IF OBJECT_ID('getMyData', 'P') IS NOT NULL
DROP PROC getMyData
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE getMyData
#some_var AS NVARCHAR(200)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql AS NVARCHAR(MAX)
SET #sql = N'SELECT * FROM myTable where id = ''' + #some_var + ''' '
EXEC sp_executeSQL #sql
END
<cfquery name="createGetMyData" dataSource="#getDatasource()#">
#preservesinglequotes(sp_1)#
</cfquery>
Try this:
<cffile action="read" file="mypath/myFile.sql" variable="sp_1">
<cfstoredproc procedure="sp_executesql" dataSource="#getDatasource()#">
<cfprocparam type="in" cfsqltype = "cf_sql_varchar" value ='#preservesinglequotes(sp_1)#'>
</cfstoredproc>
ColdFusion escapes your single quotes in db variables.
EDIT:
Secondly there is the batching of statements. the drive will batch your query as a single statement wheras the "GO" keyword is an indicator of a batch prepared. In other words, your "GO" actually IS the issue.
To fix it you will need to run 2 querys - one to drop and the other to create. Why? Because CREATE PROCEDURE actually has to be the first statement in a given batch. in MSSQL studio, using GO, you are creating 3 batches, now you have to figure out how to use one.
The good news is that your ANSI nulls and Quoted identifiers are probably not needed - they are defaulted on most instances.
Does this help?

MySql syntax question regarding CONCAT and strings

Environment is MySql 5.1.5.
This is a snippet from a larger stored procedure. Assume the variables are properly declared and set before this code is reached.
When I run the following loop, something seems to be failing in the CONCAT. #columnName and #xmlQuery are both VARCHARs. When I "SELECT #xmlQuery" at the end of the procedure, it is {null}.
If I simply replace:
SET #xmlQuery = CONCAT(#xmlQuery, #columnName);
with:
SET #xmlQuery = CONCAT(#xmlQuery, 'test');
then I get a nice string back like:
select xml_tag('result',null,null,concat(testtesttesttesttesttest
as one would expect.
WHY doesn't the CONCAT work with the local VARCHAR variable?
SET #xmlQuery = 'select xml_tag(''result'',null,null,concat(';
SET #columnCount = (SELECT COUNT(*) FROM ColumnNames);
WHILE (#rowIndex <= #columnCount) DO
SELECT #columnName = ColumnName FROM ColumnNames WHERE ID = #rowIndex;
SET #xmlQuery = CONCAT(#xmlQuery, #columnName);
SET #rowIndex = #rowIndex + 1;
END WHILE;
The problem turned out to be a conflict between the local variable #columnName and the column ColumnName in my temporary table.

How to use procedure parameters in merge statement

i'm creating a procedure to update/insert a table using merge statement(upsert).now i have a problem: using procedure parameters i have to do this upsert.
procedure xyz( a in table.a%type,b in table.b%type,....)
is
some local variables;
begin
merge into target_table
using source_table --instead of the source table, i have to use procedure parameters here
on (condition on primary key in the table)
when matched then
update the table
when not matched then
insert the table ;
end xyz;
so how to use procedure parameters instead of source table in merge statement?? or
suggest me a query to fetch the procedure parameters and use it as source table values.
help me please.
Thanks in advance.
I know that I'm eight years late to the party, but I think that I was trying to do something similar to what you were doing, but trying to Upsert based on parameters passed into a stored procedure that returns an empty string on success and an error on failure back to my VB Code. Below is all of my code along with comments explaining what I did, and why I did it. Let me know if this helps you or anyone else. This is my first time answering a post.
PROCEDURE UpsertTSJobData(ActivitySeq_in IN NUMBER,
Owner_in In VARCHAR2,
NumTrailers_in IN NUMBER,
ReleaseFormReceived_in IN NUMBER,
Response_out OUT VARCHAR2) AS
err_num NUMBER;
err_msg VARCHAR2(4000);
BEGIN
--This top line essentially does a "SELECT *" from the named table
--and looks for a match based on the "ON" statement below
MERGE INTO glob1app.GFS_TS_JOBDATA_TAB tsj
--This select statement is used for the INSERT when no match
--is found and the UPDATE when a match is found.
--It creates a "pseudo-table"
USING (
SELECT ActivitySeq_in AS ActSeq,
Owner_in As Owner,
NumTrailers_in As NumTrailers,
ReleaseFormReceived_in As ReleaseFormReceived
FROM DUAL) input
--This ON statement is what we're doing the match on to find
--matching records. This decides whether it will be an
--INSERT or an UPDATE
ON (tsj.Activity_seq = ActivitySeq_in)
WHEN MATCHED THEN
--Here we UPDATE based on the passed in input table
UPDATE
SET OWNER = input.owner,
NUMTRAILERS = input.NumTrailers,
RELEASEFORMRECEIVED = input.releaseformreceived
WHEN NOT MATCHED THEN
--Here we INSERT based on the passed in input table
INSERT (
ACTIVITY_SEQ,
OWNER,
NUMTRAILERS,
RELEASEFORMRECEIVED
)
VALUES (
input.actseq,
input.owner,
input.numtrailers,
input.releaseformreceived
);
Response_out := '';
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 3900);
Response_out := TO_CHAR (err_num) || ': ' || err_msg;
END;
Maby something like
DECLARE V_EXISTS NUMBER;
BEGIN SELECT COUNT(*) INTO V_EXISTS FROM TARGET_TABLE WHERE PK_ID = :ID;
IF V_EXISTS > 0 THEN
-- UPDATE
ELSE
-- INSERT
END IF;
END;
Also, you may try to use so-called tempotary table (select from DUAL)
CREATE TABLE TEST (N NUMBER(2), NAME VARCHAR2(20), ADRESS VARCHAR2(100));
INSERT INTO TEST VALUES(1, 'Name1', 'Adress1');
INSERT INTO TEST VALUES(2, 'Name2', 'Adress2');
INSERT INTO TEST VALUES(3, 'Name3', 'Adress3');
SELECT * FROM TEST;
-- test update
MERGE INTO TEST trg
USING (SELECT 1 AS N, 'NameUpdated' AS NAME,
'AdressUpdated' AS ADRESS FROM Dual ) src
ON ( src.N = trg.N )
WHEN MATCHED THEN
UPDATE
SET trg.NAME = src.NAME,
trg.ADRESS = src.ADRESS
WHEN NOT MATCHED THEN
INSERT VALUES (src.N, src.NAME, src.ADRESS);
SELECT * FROM TEST;
-- test insert
MERGE INTO TEST trg
USING (SELECT 34 AS N, 'NameInserted' AS NAME,
'AdressInserted' AS ADRESS FROM Dual ) src
ON ( src.N = trg.N )
WHEN MATCHED THEN
UPDATE
SET trg.NAME = src.NAME,
trg.ADRESS = src.ADRESS
WHEN NOT MATCHED THEN
INSERT VALUES (src.N, src.NAME, src.ADRESS);
SELECT * FROM TEST;
DROP TABLE TEST;
see here
Its very difficult to tell from you question exactly what you what, but I gather you want the table that you are merging into ( or on ) to be dynamic. In that case, what you should be using is the DBMS_SQL package to create dynamic SQL

Resources