Get a specific column from a returned result of SP? - sql

I have a stored procedure that returns a result, let's say it return rows of products. But each product status is not in our hand(can't get it). Our DBA just gave us another stored procedure to get the status of a product. We need to get individual product status by calling their SP. Let's say we have Product table,
CREATE TABLE PRODUCTS
(
ID INT,
Name NVARCHAR(100)
)
CREATE PROCEDURE GetProducts
AS
BEGIN
INSERT INTO #TEMPTABLE
SELECT * FROM PRODUCTS; -- Yes Too Much simplified
-- Create cursor and set additional status in #TEMPTABLE
END;
EXEC GetStatus #ProductId; -- SP That need to get status
The problem is that GetStatus is only way to get the status and this sp sometimes return 2 columns, sometimes 4 and sometimes 8. The return columns will always include Status column for sure.
If columns names is fixed then there is no problem. Is there is a way to create dynamic table at the time of executing SP.
Tried this but not working,
WITH DynamicTable AS
(
EXEC GetStatus
)

The answer to your question is no. There is no good way to get the value of a specific column returned by a stored procedure that can return a dynamic set of columns.
I say no "good" way, because of course there's a WAY. You can write an INSERT EXEC statement for every possible set of columns that the procedure can return and wrap each one in a TRY..CATCH block. If the first one errors, try the next one. As soon as you hit one that doesn't error, get the Status from it, and skip the rest.
That's the answer to your question. The solution to your problem, however, is to replace the GetStatus stored procedure with a Table-valued function. Then you can select from it, join to it, etc. I think the function would have to always return a consistent number of columns, but that would be better anyway, and the columns that aren't needed in a specific case could just be left empty or NULL.

Related

SQL Server stored procedure: how to return column names/values of type failures in variable?

Ambiguous thread name, I apologize. I am not new to SQL, but I'm new to coding longer stored procedures so I don't deal with variables much outside of passing through maybe a table name or returning row count, etc.
I have a stored procedure that is executing an insert from a staging table to a fact table. There are a couple type casts in the insert.
If the insert fails due to a typecast. Is there any way to return the name of the column that failed, along with what the failed value was? How would I code that? I know that Try_parse would make it so the stored procedure doesn't fail on type cast failure, but I want to be able to pass back exactly what column and value failed.
I show an example here:
Create Procedure dbo.Example_Insert
#updateUser varchar(255)
As
Begin
Insert Into dbo.Energy_Costs (Energy_Cost_Id, Project_Id, Propane_Cost_Dollars,
Electricity_Cost_Dollars, Fuel_Savings_Evaluator)
Select
Next Value For energy_cost_id,
r.project_id,
Cast(r.propane_cost_dollars As Decimal(18,2)),
Cast(r.electricity_cost_dollars As Decimal(18,2)),
#update_user fuel_savings_evaluator
From
staging_table r
return ##ROWCOUNT
end
You can use CURSOR in sql then insert one line at a time. When insert fail return value currently row error.
I hope my idea suitable with you.

Update from stored procedure return

I have a stored procedure that I want to run on every row in a table that matches a where clause, the procedure already exists on the server and is used in other places so it cannot be modified for these changes.
The stored procedure returns a scalar value, I need to store this value in a column in the table, I've tried using the update:
UPDATE tbl SET tbl.Quantity =
EXEC checkQuantity #ProductID = tbl.ProductID, #Quantity = tbl.Quantity
FROM orders tbl WHERE orderNumber = #orderNumber
But this of course doesn't work, is there a way to do this without multiple queries, reading the line info, running the proc in a loop then updating the original line?
No there is no way to do this without multiple queries. This is one of the few scenarios where a cursor or loop is necessary.
Unless you can replace your stored procedure with a user-defined function, which can be run in the context of a single query.

Whilst creating a SQL function, how do i check whether a table is used in the current query that the function is called into?

My main query is:
SELECT
a,
b,
c,
my_function(d),
into
temp
from
trade t,
party pt,
portfolio pr
What I want my function to do is check if a particular table is used in the join (for eg, the table 'portfolio'). If so, than it will execute a certain block of code and return some value. If the table does not exist, it will proceed to next block of code within the function and return some value.
What i want to know is how do i accomplish the part of checking if a particular table is used in the current query/join and 'code' this check into the function? I am not looking to check if the table is present in the database, but only if it is present in the current query that the function is being called in.
Function will be something like:
`
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION maturity_date
(
-- Add the parameters for the function here
#d int>
)
RETURNS date >
AS
BEGIN
-- I want to do the check here.I wnat to check if a particular table exists,
-- if so then execute the 1st block, else execute 2nd block
--1st block
Begin
RETURN end_day
End
Else
--2nd block
Begin
RETURN expiry_day
End
END
GO
`
The function has no inherent access to the query that called it.
The only way the function could know if a table was present in the calling query is if you passed it as a parameter.
EDIT: After reading the edit to your question, my answer above is still accurate, but I would further propose that I think you would be better off writing two functions. SQL Functions should be simple and do only one thing. Writing a single function that does one thing in one case, and something different in another case is over-consolidating.

How to prevent SQL from returning multiple resultsets

The issue I'm facing is that I have a stored procedure (lets call it sp_one), which during it's run calls another stored procedure (lets call it sp_two).
I'd only like the resultset from sp_one to be returned at the end, and not those from sp_two. I imagine there is a way to capture the results from sp_two that will prevent them from also being returned but haven't been able to figure the syntax for this.
Any ideas?
Some pseudo code which captures the essence of what is going on (not my actual code):
CREATE PROCEDURE sp_two AS
BEGIN
update Users
set is_valid = 0
select * from Users
END
CREATE PROCEDURE sp_one
AS
BEGIN
exec sp_two
select * from Users
END
exec sp_one
The result of running exec sp_one is the resultset from sp_two, then the results from sp_one. (eg. the users table twice).
First of all, here is a similiar question
I don't recommand to use this kind of solution, because it could be a bottleneck easily. I would say you should focus on to make the dataprocessing on a much clearer way (however I understand that your question's example is just a theoretical example)
But if you really want to use something like this I would say measure the danger of the returning rows:
1: How many rows returns?
2: How wide is the returning set?
And if you think "ok it is not a big deal", then I would say use a memory table instead of temp table (do not make physical writes):
DECLARE #users TABLE (...fields here...)
INSERT INTO #users
EXEC sp_two
In sp_one, you can use
CREATE TABLE #temporaryusers (Usertable fields here)
INSERT INTO #temporaryusers
EXEC sp_two
DROP TABLE #temporaryusers
to swallow your results.

How can a stored procedure return ROWCOUNT?

I have written stored procedure which has 2 Insert queries and 1 Update query inside it. Of all these,either insert queries or update query are executed at a time. Now my problem is to get ROWCOUNT in each case. Say suppose if insert operations are executed,then I want stored procedure to return ##ROWCOUNT to the calling application, so that the application will be aware of whether the required operations executed correctly or not. Can anyone suggest/tell me how can I get the rows affected from the stored procedure?
Use Output parameters in your stored procedures to return the RowCount of your inserts / updates.
Refer MSDN link for more information on how to use Output params
You can have multiple output params so you can have 2 different output params one each for your insert and the 3rd for your update statement.
Example:
CREATE PROCEDURE GetEmployeeData
#employeeID INT,
#managerID INT **OUTPUT**
AS
BEGIN
....
....
Additionally, you can always concatenate the rowcounts of your 2 Inserts / Update using delimiters and return them as one value eg: "10;0" - However that is the old fashioned and "I would not recommend" approach.
Also, you could create a table variable and return the table with rows = number of Inserts / updates and the value of the column = RowCount affected.