How to get data back from stored procedure - database

I'm trying to debug\execute a SP from t-sql (sql server 2008) and when I execute the following sql it returns only a message 'Command(s) completed successfully'.
I know the SP is returning the data in a table via the #RETURN_VALUE parameter, how do I get this to display in sql query window.
exec STARMS.dbo.GetMetaData ##Assembly=13366,##Namespace=NULL,##ParameterName=NULL,##Standard=0,##Timestamp=NULL
The SP looks something like this ( removed the main body) the interesting part is the creation of the temp table and then returning the contents of the temp table:
CREATE PROCEDURE [dbo].[GetMetaData]
##Assembly Sql_Variant = NULL,
##Namespace Varchar(30) = NULL,
##ParameterName Varchar(40) = NULL,
##Standard Bit = 0,
##Timestamp DateTime = NULL
AS
SET NOCOUNT ON
DECLARE #ResultTable TABLE (AssemblyId Int, Namespace Varchar(30), ParameterName Varchar(40), Value Varchar(100))
-- Does loads of stuff and then inserts into #ResultTable table...
SET NOCOUNT OFF
-- Return the result
SELECT AssemblyId, Namespace, ParameterName, [Value]
FROM #ResultTable
RETURN
Note: the reason I'm asking the question is because I'm trying to look at the performance of the SP in SQL Server 2008 and I'm unsure why this doesn't return the data in the query window.

Check your full code of SP, may be somewhere there is a RETURN statement, so - the SP will not return any data (pay attention on IF SomeContition IS TRUE RETURN):
CREATE PROCEDURE [dbo].[GetMetaData]
##Assembly Sql_Variant = NULL,
##Namespace Varchar(30) = NULL,
##ParameterName Varchar(40) = NULL,
##Standard Bit = 0,
##Timestamp DateTime = NULL
AS
SET NOCOUNT ON
DECLARE #ResultTable TABLE (AssemblyId Int, Namespace Varchar(30), ParameterName Varchar(40), Value Varchar(100))
-- Does loads of stuff and then inserts into #ResultTable table...
IF SomeContition IS TRUE RETURN
SET NOCOUNT OFF
-- Return the result
SELECT AssemblyId, Namespace, ParameterName, [Value]
FROM #ResultTable
RETURN

Related

Column values as stored procedure input

I have the following code when inputting parameters for a SP:
USE [MDAmanager]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[spCougarExport]
#PropertyCodeString = NULL,
#Date = NULL,
#InferDate = NULL,
#TransactionCodeString = NULL
SELECT 'Return Value' = #return_value
GO
For the #PropertyCodeString I would like to pass the values from a seperate table with all the property codes.
Below is an example of the property codes
What I'm trying to achieve is have the SP always return all properties and not require updating the property codes when a new property is added.
Any assistance or direction would be greatly appreciated.
Assuming you are able to amend your SP then you can utilise a user defined table type e.g.
CREATE TYPE [dbo].[PropertyCode_UDT] AS TABLE
( [PropertyCode] [bigint] NOT NULL
)
GO
DECLARE #PCTab [dbo].[PropertyCode_UDT]
;
INSERT INTO #PCTab
( [PropertyCode]
)
SELECT PC.[PropertyCode]
FROM [dbo].[PropertyCode] PC
;
DECLARE #return_value int
EXEC #return_value = [dbo].[spCougarExport]
#PropertyCode = #PCTab,
#Date = NULL,
#InferDate = NULL,
#TransactionCodeString = NULL
;
Your Sp will need to be amended to accept the correct type for #PropertyCode and you can just join your query within the SP on this table to get all the Property Codes
Eg
CREATE PROCEDURE [dbo].[spCougarExport]
#Date [date]
, #InferDate [date]
, #TransactionCodeString [nvarchar] (MAX)
, #PropertyCode PropertyCode_UDT READONLY
AS BEGIN;
.......
SELECT ...
FROM #PropertyCode atPC

SQL stored procedure - table as parameter

I have a database with different tables (all the same structure) where I'd like to run a stored procedure having a parameter that defines which table to query.
I can't seem to figure it out:
CREATE SCHEMA test;
GO
First I created a schema
CREATE TYPE DataType as TABLE (
[datetime] [datetime] NULL,
[testVar] [bigint] NULL)
GO
Then I created the table type
USE [TestDataFiles]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [test].[testing]
(
-- Add the parameters for the stored procedure here
#datetime datetime,
#t DataType READONLY
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
select top(10) *
from #t
where [datetime] > #datetime
END
GO
Then I created the stored procedure.
Exec test.testing #t = 'table.1', #datetime = '2017-01-01'
However when I call it I get the following error:
Msg 206, Level 16, State 2, Procedure test, Line 0 [Batch Start Line 0]
Operand type clash: varchar is incompatible with DataType
Same happens with:
Exec test.testing #t = [table.1], #datetime = '2017-01-01'
I have seen an example where in the procedure between the begin and select you put something like:
INSERT INTO table.1
( datetime, testVar)
But table.1 (or table.2 etc as I have a list of tables) has data and I don't want to change it.
Unless I'm meant to create a dummy table like I did the TYPE?
The examples I've found online havent been useful.
To do that you will need to use dynamic SQL
The basic procedure is to build up a string that will hold the statement you will execute, then execute it
declare #SQL nvarchar(1000)
declare #t as nvarchar (1000)
set #t = 'MyTable'
set #Sql = 'Select * from ' + #t
exec sp_executesql #sql
You have to pass parameter of type DataType. So, create variable of that type and pass it into stored procedure like
declare #table1 DataType
INSERT INTO #table1(datetime, testVar) values (..., ...)
Exec test.testing #datetime = '2017-01-01', #t = #table1

Is this T-SQL stored procedure written correctly?

I am new to SQL Server and T-SQL, but I do have some experience building applications in MS Access.
This stored procedure runs fine when I execute it from the application, however when I am debugging it in SSMS, I get an error
Unable to Step. Invalid Operation.
but it will allow me to step through. Based on my research, it seems like I am creating a race condition but I have not been able to correctly fix the issue. I would also appreciate any advice to optimize this or fix any issues that are apparent.
What the code does:
This code is to enter a new customer into the database. The first select statement looks for an existing ID. If the ID is null, it will add a new customer. If the ID is not null, it will not add the customer. The same goes for the second IF statement to check if #pName2 and #pName3 are null before inserting these values.
Here is my code:
#pUID nvarchar(16) = null,
#pName1 nvarchar(50) = null,
#pName2 nvarchar(50) = null,
#pName3 nvarchar(50) = null,
#pAddress1 nvarchar(30) = null,
#pAddress2 nvarchar(30) = null,
#pAddress3 nvarchar(30) = null,
#pZipCode nvarchar(30) = null
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ID INT
SELECT #ID = ID FROM tblCustomer WHERE strUID = #pUID
IF #ID IS NULL
BEGIN
DECLARE #Customer_ID INT
INSERT INTO tblCustomer(strUID, strName)
VALUES(#pUID, #pName1)
SET #Customer_ID = ##IDENTITY
IF (#pName2 <> '') OR (#pName3 <> '')
BEGIN
INSERT INTO tblSecondaryCustomer(CustomerID, strName2, strName3)
VALUES(#Customer_ID, #pName2, #pName3)
END
INSERT INTO tblAddress(CustomerID, strAddress1, strAddress2, strAddress3, strZipCode)
VALUES(#Customer_ID, #pAddress1, #pAddress2, #pAddress3, #pZipCode)
END
END
Try replacing your IF statement with the following:
IF NOT EXISTS(SELECT ID FROM tblCustomer WHERE strUID = #pUID)
It doesn't seem your using #ID other than a check for existence...and you can use the ISNULL function to make sure you cover NULL cases...
IF (ISNULL(#pName2,'') <> '') OR (ISNULL(#pName3,'') <> '')
HTH
Dave

how to write update procedure with scope identity

My insert procedure is working fine the way i want. But update is not working with scope identity.
SET ANSI_NULLS ON
ALTER PROCEDURE [dbo].[spr_unitCreation]
(
#Unit_Name VARCHAR(50) = NULL,
#Unit_Abbreviation VARCHAR(50) = NULL,
#Unit_type VARCHAR(50) = NULL,
#Decimal_Places VARCHAR(50) = NULL,
#Description VARCHAR(50) = NULL,
#Super_Unit VARCHAR(50) = NULL,
#Per_Unit VARCHAR(50) = NULL,
#unit_Id INT OUTPUT,
#abc VARCHAR(50) = NULL
)
AS
BEGIN
IF #abc = 'update' BEGIN
SET NOCOUNT ON;
SELECT #unit_Id AS SCOPE_IDENTITY
UPDATE tbl_UnitCreation
SET Unit_Name = #Unit_Name,
Unit_Abbreviation = #Unit_Abbreviation,
Unit_type = #Unit_type,
Decimal_Places = #Decimal_Places,
Description = #Description,
Super_Unit = #Super_Unit,
Per_Unit = #Per_Unit
WHERE unit_Id = #unit_Id
END
END
SELECT * FROM tbl_UnitCreation
SCOPE_IDENTITY returns the last identity value inserted into an identity column. You are not inserting a row.
To update a row all you need is to pass a value to #unit_Id when executing [spr_unitCreation]. Also remove the line "SELECT #unit_Id AS SCOPE_IDENTITY" from your code.
Based on the comments, you need to find the correct id by searching on relevant details. So you can get the id like this:
SELECT #unit_Id = unit_Id
FROM tbl_UnitCreation
WHERE Unit_Name=#Unit_Name -- NB: Ensure this column contains your relevant details
Another commonly used option is to use the OUTPUT clause of the UPDATE statement, inserting all the updated/"inserted" primary keys and Unit_name into a tablevariable.
https://learn.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-2017

Create a table and default column value to a received variable parameter

I'm working on a MSSQL stored procedure.
I receive a table valued parameter (#accountPropsTVP) and a single variable (#accountID) from the C# server.
#accountPropsTVP has 2 columns:
valueTypeID int
value varchar(max)
Note: I'm never sure how many rows will be in this table.
#accountID is an int.
I need to merge everything received into one table, so that it ends up looking like so:
#temporaryTable:
#accountID (always the same for all rows)
valueTypeID
value
Below is what I have tried, but I get an error:
Msg 112, Level 15, State 4, Procedure insertAccountProps, Line 20
Variables are not allowed in the CREATE TABLE statement.
CREATE PROCEDURE insertAccountProps
-- Received parameters
#accountID int,
#accountPropsTVP accountPropsTVP READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
-- declare new table
DECLARE #accountPropsTemp TABLE
(
accountID int not null DEFAULT (#accountID),
valueTypeID int not null,
value varchar(max) not null
)
-- insert received TVP into new temp table, so that we can manipulate it (tvp's are read only :( )
INSERT INTO #accountPropsTemp
SELECT *
FROM #accountPropsTVP
-- select all from TVP and add it into temp table created above
INSERT INTO dbo.accountsProps
SELECT *
FROM #accountPropsTemp
END
GO
Maybe there's a simpler way of doing this?
Your issue is here:
DECLARE #accountPropsTemp TABLE
(
accountID int not null DEFAULT (#accountID),
valueTypeID int not null,
value varchar(max) not null
)
You're assigning a variable as a default value which as the error message clearly states is not allowed.
The best option for this is to change your syntax to:
DECLARE #accountPropsTemp TABLE
(
accountID int not null,
valueTypeID int not null,
value varchar(max) not null
)
INSERT INTO
#accountPropsTemp
SELECT
#AccountID
,ValueTypeID
,Value
FROM
#accountPropsTVP

Resources