Table Design for storing dynamic SQL and Stored procedure - sql-server

I want to store few compiled stored procedure in a table and want to fire them dynamically. The procedures will be fired in an another procedure name GetDetails. I have designed the table as following:
Table: SQLtab
Id SQLText ParamId
1 GetProdDetails 1
2 GetSuppDetails 2
Table: SQLParams
ParamId SQLParam
1 prodId
2 suppId
The parameters of the compiled procedure will be determined by the outer procedure (GetDetails) which will read the procedure names from the SQLtab table and fire them. So, I cannot store the procedure parameter values in the table. The procedure GetDetails runs a query and determines the parameter values for prodId, suppId. I am planning to create a temporary table to store parameter values as following:
Id SQLText ParamVal
1 GetProdDetails 10
2 GetSuppDetails 12
Once the temporary table is created in the outer procedure, I can fire the procedures dynamically using parameter values. Somehow, I feel this is not the best table/procedure design. Could anybody suggest a better design?

Why bother creating these tables and maintaining them when SQL Server cataloge views does it for you.
I would simply use the following query to get the procedure name and its parameters
SELECT po.name AS [Proc Name]
,pa.name AS [Param Name]
FROM sys.procedures po
INNER JOIN sys.parameters pa ON po.object_id = pa.object_id
WHERE po.name LIKE '%ProcName%'
-- AND po.is_ms_shipped = 0 --<-- add more filters as required

Related

Get first N records from stored procedure result set in SQL Server

Is there is any solution / query to get first N records from stored procedure result without retrieving the whole result set?
Consider my stored procedure returns 3 million rows, and I just want the first 10 rows from it.
The best approach would be to alter your stored procedure to be able to include a parameter for the TOP filter.
However, you could also use
SET ROWCOUNT 10
EXEC MyProc
Be careful to reset the value of ROWCOUNT afterwards otherwise you may impact other queries.
The downside is that you cannot control the order of the rows. I also haven't tested with such a large result set to identify whether this does reduce resource consumption enough.
You can use TOP clause to achieve it
Syntax
SELECT TOP number|percent column_name(s)
FROM table_name
WHERE condition;
Let's say that you have Your_stored_procedure return list of users
CREATE PROCEDURE Your_stored_procedure
AS
SELECT UserId, UserName
FROM yourtable
GO;
At here, you need to create temp table to store value from stored procedure
-- Check result
CREATE TABLE #TempTable
(
UserId INT,
UserName varchar(100),
)
INSERT INTO #TempTable(UserId, UserName)
EXEC Your_stored_procedure
Then you can get the result like this way
SELECT TOP 10 UserId, UserName
FROM #TempTable
ORDER BY UserId -- As #Squirrel's comment, TOP should come with ORDER BY
Note
You should make sure that the number of columns in your table according to the structure of the stored procedure.
Updated
As #Vinod Kumar's comment, you can also achieve it by using OPENQUERY like below
SELECT top 1 * FROM OPENQUERY ([MyServer], 'EXEC [VinodTest].[dbo].[tblAuthorsLarge] year = 2014')
You can use Fetch next clause. Please refer this for more information.
SELECT column-names
FROM table-name
ORDER BY column-names
OFFSET n ROWS
FETCH NEXT m ROWS ONLY

Use result of stored procedure to join to a table

I have a stored procedure that returns a dataset from a dynamic pivot query (meaning the pivot columns aren't know until run-time because they are driven by data).
The first column in this dataset is a product id. I want to join that product id with another product table that has all sorts of other columns that were created at design time.
So, I have a normal table with a product id column and I have a "dynamic" dataset that also has a product id column that I get from calling a stored procedure. How can I inner join those 2?
Dynamic SQL is very powerfull, but has some severe draw backs. One of them is exactly this: You cannot use its result in ad-hoc-SQL.
The only way to get the result of a SP into a table is, to create a table with a fitting schema and use the INSERT INTO NewTbl EXEC... syntax...
But there are other possibilities:
1) Use SELECT ... INTO ... FROM
Within your SP, when the dynamic SQL is executed, you could add INTO NewTbl to your select:
SELECT Col1, Col2, [...] INTO NewTbl FROM ...
This will create a table with the fitting schema automatically.
You might even hand in the name of the new table as a paramter - as it is dynamic SQL, but in this case it will be more difficult to handle the join outside (must be dynamic again).
If you need your SP to return the result, you just add SELECT * FROM NewTbl. This will return the same resultset as before.
Outside your SP you can join this table as any normal table...
BUT, there is a big BUT - ups - this sounds nasty somehow - This will fail, if the tabel exists...
So you have to drop it first, which can lead into deep troubles, if this is a multi-user application with possible concurrencies.
If not: Use IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='NewTbl') DROP TABLE NewTbl;
If yes: Create the table with a name you pass in as parameter and do you external query dynamically with this name.
After this you can re-create this table using the SELECT ... INTO syntax...
2) Use XML
One advantage of XML is the fact, that any structure and any amount of data can be stuffed into one single column.
Let your SP return a table with one single XML column. You can - as you know the schema now - create a table and use INSERT INTO XmlTable EXEC ....
Knowing, that there will be a ProductID-element you can extract this value and create a 2-column-derived-table with the ID and the depending XML. This is easy to join.
Using wildcards in XQuery makes it possible to query XML data without knowing all the details...
3) This was my favourite: Don't use dynamic queries...

Determine Tables Referenced By Letters In Stored Procedure

I have a stored procedure that references a few tables. However, it refers to the tables with letters.
So let's say a column called Name is from the table Users, then the stored procedure may call the column name U.Users.
My question is, how do I get a list of all such mappings i.e all the letters that map to a table?
you are referring to table aliases, each distinct query can have their own "mapping". These alias values are not specific to stored procedures. Here is an example:
select
a.col1, a.col2
FROM YourTable1 a
select
b.col1, b.col2
from YourTable2 a
inner join YourTable1 b on a.col1=b.col2
YourTable1.col1 and YourTable1.col2 are returned in both of the above queries, although they have the "a" alias in the first query and "b" alias in the second query. See this Using Table Aliases.
In examples like above, people often use a table alias because is is quicker to write a.col1 than YourTable.col1. There is no way for anyone to know the aliases used in your stored procedure, you need to figure that out, look at these examples to help:
FROM YourTable a
-- ^table ^alias
FROM YourTable AS a
-- ^table ^alias
FROM YourTable1 a
INNER JOIN YourTable2 b ON a.col1=b.col1
-- ^table ^alias
FROM YourTable1 AS a
INNER JOIN YourTable2 AS b ON a.col1=b.col1
-- ^table ^alias
Each statement assigns its own aliases for the tables it uses, if at all. The same table used in different statements could be aliased differently (or not aliased). There cannot possibly be a single place to look up every table alias or a simple method to recover them from all the statements in your stored procedure or function or view etc.

Assign multiple data to a variable in sql server stored procedure

I want to assign multiple values to a variable from a SELECT statement in a stored procedure.
The code goes like this
DECLARE #ProjectExecutionPlanId INT=NULL
SELECT #ProjectExecutionPlanId = (SELECT [ID] FROM [dbo].[ProjectExecutionPlan]
WHERE ProjectDetailID=#PID)
#PID in the input to the stored procedure.
The SELECT statement returns multiple values. So I am getting error.
This answer is based on your comment:
I want to delete multiple rows from the ProjectExecutionPlanExecution
table which is dependent on ProjectExecutionPlan table.There are
multiple plans in ProjectExecutionPlan table. So I will get multiple
IDs
Delete From ProjectExecutionPlanExecution
Where ProjectExecutionPlanId In (SELECT [ID]
FROM [dbo].[ProjectExecutionPlan]
WHERE ProjectDetailID=#PID)
Or
Delete pe From ProjectExecutionPlanExecution pe
Join ProjectExecutionPlan p On pe.ProjectExecutionPlanID = p.ID
WHERE p.ProjectDetailID=#PID

Creating a procedure for creating a table with dynamic number of columns

I'm trying to create a procedure that can create a table with not specific number of columns.
My query returns a value of 3 meaning it needs 3 columns (has to be dynamic).
I have create a #variable to set the name string of the tables but I don't know how to formulate the CREATE TABLE statement to actually create the table with the columns from this string.
Any kind of help would be appreciated guys.
You can get the columns on a table out of the sql database with
select
bb.name,
bb.colid
from sysobjects aa
inner join syscolumns bb
on aa.id = bb.id
where aa.name ='tblMyTable'
The name is the column name, the ID the number. You could select column names from the list and use dynamic sql to build a select. Not sure how you decide what columns you are after from the table.

Resources