Query with variable assignment not returning results - sql

I have the below query that uses variables, however I want to be able to run this and have results shown from the Select statement. All I am getting is a Message "Commands completed Successfully" instead. I have tried tinkering with the advanced Query Options with checking the 'SET NOTEXEC' option but this did not yield results.
DECLARE #ErrorCount AS INTEGER;
DECLARE #MinErrorDateTime AS DATETIME;
SELECT #ErrorCount = COUNT(IBTRANSACTIONID)
,#MinErrorDateTime = MIN(ERRORTIMESTAMP)
FROM PSIBERR
WHERE MESSAGE_NBR <> 0
AND ERRORTIMESTAMP >= DATEADD(mi,-62,GETDATE())

This should work for you.
You need to do an additional select statement. After your query add this. Also, if this were a stored procedure you could add the variables as Output variables to return the values.
Select #ErrorCount as ErrorCount, #MinErrorDateTime as MinErrorDateTime

Related

How to use an if/else statement inside the sql condition for SAPB1UP

Here is the code inside the SQL condition
DECLARE #cc NVARCHAR(MAX)
DECLARE #dn NVARCHAR(MAX)
DECLARE #stc NVARCHAR (MAX)
SET #cc = $[$4.0.0]
SET #dn = $[$8.0.0]
SET #stc = $[$40.0.0]
IF(SELECT COUNT(*) AS Type
FROM dbo.ORDR INNER JOIN
dbo.CRD1 ON dbo.ORDR.CardCode = dbo.CRD1.CardCode AND dbo.ORDR.ShipToCode = dbo.CRD1.Address
WHERE (dbo.ORDR.DocStatus = 'O') AND (dbo.CRD1.CardCode = #cc) AND (dbo.ORDR.DocNum = #dn)AND (dbo.ORDR.ShipToCode = #stc)) = 0
BEGIN
SELECT 'address' FOR BROWSE
END
ELSE
BEGIN
SELECT 'success' FOR BROWSE
END
Here is the error I am getting
Essentially when I click update or anything, it should give me an error message stating that the company's name was changed in the business partner, please validate it.
I believe the query is correct as it narrows it down to the exact, docnumber, cardcode, and shiptoaddress.
[
In the picture, the "Address" is different from the "ShipToCode"
So now all I want to do is essentially make a comparison between the two values in the two column names. If the 2 values don't match, execute the error message. Problem is, I cant link the items together in the B1UP, so I was hoping to do it in the sql, either it updates the "Address" to the "ShipToCode" or like in the b1up, it would give an error message so you would have to manually validate the them.
EDIT: So I think I figured it out but I don't know how to use count() properly. For example, if a line does NOT exists after the count, the query would be set to false and the error message would be chosen. Everything in the query is now correct except I just need to implement count somehow so it would state that the query is false and then it would choose the error message like I reiterated earlier

Same query, different result after removing USE DatabaseName GO

My function GetProductDesc (when called) returns a different result after commenting out USE DatabaseName GO. I don't even know where to start debugging this. The pictures tell the story. I had to blur out a lot but you can see that the results are clearly different. Keep in mind that the pictures are not the function code, they are calling the function GetProductDesc
So strange. Any suggestions? I have an expert helping me later today but I had to share.
EDIT:
The function uses another lookup table in the same database. There is no Top or Order By clause. It calculates the product description based on the input components (numbers). It will return a different result if the input numbers are different, but here the input numbers are the same!
The function has been in place and working for over 5 years. I believe the problem started at about the time the version of SQL Server was updated recently.
EDIT 2 with partial answer:
The problem is caused by ##RowCount. It appears to be a breaking change caused by our recent migration to SQL Server 2019 although I haven't found the problem documented. The function returns a different product description based on ##RowCount following a Select statement. Internally the function does something like this:
SELECT Fields FROM Table WHERE Field = #Variable
IF ##Rowcount = 1
Return ProdDesc1
ELSE
Return ProdDesc2
After the SQL Server migration ##RowCount here was different depending on whether
USE DatabaseName
GO
was present.
The solution was to replace ##Rowcount with a variable #RowCount. This new code works:
DECLARE #RowCount INT = 0
SELECT Fields, #RowCount = #RowCount + 1
FROM Table WHERE Field = #Variable
IF #RowCount = 1
Return ProdDesc1
ELSE
Return ProdDesc2
If you have SQL Server 2019 installed try this to recreate the problem:
USE Master
GO
Select ##ROWCOUNT
The result here is ##ROWCOUNT = 0
Now comment out the two top lines:
--USE Master
--GO
Select ##ROWCOUNT
The result is now ##ROWCOUNT = 1
Anybody know why?
There is a SQL Server 2019 cumulative update from Microsoft that fixes this problem.

How do I run selected SQL queries with variables included?

I want to be able to run a snippet of my SQL query by selecting it and pressing F5. Issue is, if that selection contains a variable name I get an error: Must declare the scalar variable "#variableName".. Is there anyway to resolve this? I want variableName to be the value it would otherwise be had I run the whole statement at that moment in time that I've selected...
Sample of full code:
DECLARE #cat INT;
SET #cat = 2;
SELECT * FROM TableName
WHERE ColumnName = #cat;
Sample of my selection that I want to run without including declaration/set lines:
SELECT * FROM TableName
WHERE ColumnName = #cat;
Probably not possible but I figured it'd be worth a shot.
P.S. I'm a SQL noobie so if I'm missing something obvious let me know!
I understand where you are coming from. This is a snippet in a long procedure or something and naturally you want to keep the declarations at the top, which I agree with. In this case, when you are testing, the only real way to circumvent this is to re-declare it and set it at the top of your snippet. Then, when you are running the entire batch of code just comment out this line. Otherwise you'd have to wrap the snippet in a try / catch block to try and catch compile errors which is tricky.
Also, this is usually how I've seen people put a select * from someWorkTable to test results along the way. Then it's commented out when the batch is ran.
Left click on table name, right click design and you are able to view the datatype of the column name.
if it is nvarchar..
DECLARE #cat INT;
SET #cat = 2;
Convert(varchar, #cat)
SELECT * FROM TableName
WHERE ColumnName = #cat;
OR
directly declare
DECLARE #Cat VARCHAR(3)
SET #cat = '2'
SELECT * FROM TableName
WHERE ColumnName = #cat;
Hope this helps
You can simulate your variable as declared in a select query with an alias result. Then you can just use alias.column as part of your join...
SELECT
TN.*
FROM
( select '2' as TmpColumn ) tmpAlias
JOIN TableName TN
on tmpAlias.TmpColumn = TN.ColumnName
this way, no "scalar" variable is required, but not as practical as a simple parameterized query using a direct WHERE clause. Additionally, you could use the alias.column throughout in case you had other tables relations, etc or even additional "variables" you wanted to apply in your query.

How to stop results of nested stored procedure showing up at top level?

I've made an alteration to an existing stored procedure (dbo.pr1) so that it now calls a second stored procedure (dbo.pr2).
Both of these stored procedures return data with a final SELECT query.
In dbo.pr1 I've now added the line:
EXEC #var1 = dbo.pr2
I've done this in order to assign the values in dbo.pr2 to the variable #var1 (dbo.pr2 returns a single bit).
However, now when I execute dbo.pr1 I get two results back instead of the expected one. I get the SELECT query results at the end of dbo.pr1 but I also get the SELECT query result from dbo.pr2.
I cannot alter dbo.pr2 as it's being used elsewhere in the system. Is there a way that I can stop its result showing up when I execute dbo.pr1?
Do something with what is returned in the caller,
SET NOCOUNT ON;
...
DECLARE #resultsOfPr2 TABLE
(
...
);
INSERT #resultsOfPr2
EXEC #var1 = [dbo].[pr2];
Fiddle here
Note: I'm assuming [dbo].[pr2] selects a single result set.

How to set the result of exec stored procedure to a variable?

I need to exec a stored procedure and store its scalar result to a local variable inside a stored procedure.
How to implement?
E.G.
CREATE PROCEDURE [dbo].GetNthNo AS
DECLARE #a INT
DECLARE #d INT
DECLARE #n INT
DECLARE #S INT
SET #S=EXEC spGetNthNo #a,#d,#n
SELECT #S
Please help.
Instead of:
SET #S=EXEC spGetNthNo #a,#d,#n
You need:
EXEC #S = spGetNthNo #a,#d,#n
And then within the procedure, you need something like:
RETURN 100
or:
RETURN #x
for the value you want for #S after the procedure executes.
You can also use output parameters. Combined example:
IF OBJECT_ID('tempdb..#example') IS NOT NULL DROP PROCEDURE #example
GO
CREATE PROCEDURE #example
#output_param INT OUTPUT
AS BEGIN
SET #output_param = 100
RETURN 200
END
GO
DECLARE #return INT, #param INT
EXEC #return = #example #output_param = #param OUTPUT
SELECT #return as [return value], #param as [output parameter]
Try something like that
CREATE PROCEDURE Test
#RetVal INT OUT
AS
BEGIN
SET #RetVal = 99
END
DECLARE #X INT
EXEC Test #X OUT
PRINT #X
Edit: [comment following posting of T-SQL snippet in question]
You seem to need a wrapper, around the spGetNthNo Stored Procedure, maybe because this existing procedure doesn't return its result in the way that is desired. An alternative to a wrapper may simply be to modify [ever so slightly] spGetNthNo itself, so it works as desired in the first place (provided the method is not currently in use with its existing API).
Regardless of whether the changes will be in the original SP or in a wrapper, there are two distinct ways of retrieving data from an SP:
With output variables (as shown above)
By having the SP return a "recordset", i.e. a table made of rows (records) and columns (fields). (This is done by having a SELECT statement towards the end of the SP, as show in the question snippet)
With the output variable approach, the data is readily placed in the variables by the time the SP returns. With the recordset apporach, the calling logic needs to "consume" the data returned, in a similar fashion that it would from a SELECT statement.
Aside from the way the returned data is consumed, there are a few differences between these approaches.
The most obvious one is that the "recordset" approach allows the returning more values: one would have to explicitly declare say 30 variables (with some naming convention aimed at helping with the two-dimensional nature of the table) to emulate a the returns of a SP which "SELECT TOP 10 a, b, c FROM myTable". Also the SP would have to explicitly set each of the these output variables.
Another related but more subtle difference is that the recordset approach allows returning a number of rows and columns that is undefined at the time of the call. The number and types of the variables do not need to be expressed beforehand, rather they come with the metadata surrounding the recordset.
In short: the output variable approach is more suited to return a fixed set of a few variables, such as status code, maximum or minim value (or other aggregate values and calculations), or also, a few fields from a expected single record. The Recordset approach is used when the purpose of the stored procedure is to effectively provide a table-like result, or when it returns very many values, such as a long [and evolving] list of aggregate values, etc.