SQL Server 2008 R2 stored procedures - sql

I am facing a problem with my slow improvement in SQL Server 2008 R2 and here is the case:
I want to create a stored procedure that accepts parameters, but I want it to work in a special way so that if I pass 2 parameters in search in a table patient for example where as if I pass to it one parameter I want it to search in a table school and so on.
Any help will be really appreciated
Thank you
USE []
GO
/****** Object: StoredProcedure [dbo].[proc_search_patient_ByID] Script Date: 11/28/2014 07:47:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[proc_search_patient_ByID]
(
#PatID_pk int ,
#Cntid smallint,
#FamID int
)
AS
SET NOCOUNT ON
select cntid AS Center , PatFName AS FirstName , PatMName AS MiddleName , PatLName AS LastName , PatMother AS MotherName ,PatDOB AS DOB
from tbl
where Cntid=#Cntid and PatId_PK = #PatID_pk
i want my procedure to work in this way if i supply 2 param but if i supply #FamID i want it to search in completely another table

Try passing null value for unused parameters and inside the stored procedure put a check for nulls to switch tables.
CREATE PROCEDURE [dbo].[proc_search_patient_ByID]
(
#PatID_pk int ,
#Cntid smallint,
#FamID int
)
AS
SET NOCOUNT ON
IF #Cntid IS NULL
BEGIN
--Use select stmt of a table
END
ELSE
--Use select stmt of another table
BEGIN
END
Likewise switch tables with appropriate parameters.

Related

Stored Procedure Output Value Not Updating

Everyone.
I have created a stored procedure in SQL Server 2016 that has the purpose of giving the of the total number of sales recommendations [#Recommendation in Recommendations table] in my table that contain this string: '____Document DOB in sales record' past any given date. I want to put this result into a temporary table as well.
Helpful Table Info:
Reference Table where I am grabbing the data: Recommendations
The relevant fields in the Recommendations table are #Recommendation, and #SalesProcessTime
The #Recommendation field is a VARCHAR(255), and #SalesProcessTime is a DATETIME
Regardless of what I change the date to - or even if I make it =, >=, etc - the same numeric value is displayed.
If you need anything else, please don't hesitate to ask me.
USE [Test_Database]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE usp_SalesRefCount
AS
BEGIN
--IF OBJECT_ID('tempdb..DocDOB') IS NOT NULL DROP TABLE #DocDOB
DECLARE #NumRecs INT;
-- Count of the number of recommendations
SELECT #NumRecs = COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > '2018-10-20'
CREATE TABLE ##RefCount (NumberOfRecs INT);
INSERT INTO ##RefCount
SELECT #NumRecs
END
EXEC usp_SalesRefCount
SELECT * FROM ##DocDOB
Why are you using a global temporary table at all? Why not just return the results from the procedure directly? eg:
CREATE PROCEDURE usp_SalesRefCount
AS
BEGIN
DECLARE #NumRecs INT;
SELECT #NumRecs = COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > '2018-10-20'
SELECT #NumRecs NumRecs
END
You are inserting data into a global temporary table "##RefCount" and selecting from another one "##DocDOB", so the result will never change.
Anyway, as #DavidBrowne said, you should just return the result directly
CREATE PROCEDURE usp_SalesRefCount
AS
BEGIN
SELECT COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > '2018-10-20'
END
Also, another idea, maybe get that date as a parameter, so you don't have to update the stored procedure when you need to select by another date
CREATE PROCEDURE usp_SalesRefCount
#selectDate DateTime
AS
BEGIN
SELECT COUNT(Recommendation)
FROM [Master_AGGREGATE].[dbo].[Recommendations]​
WHERE Recommendation = '____Document DOB in pt record' ​
and SalesProcessTime > #selectDate
END

Several stored procedure problems

I just started working with stored procedures. I have 2 problems.
When I create an object with a new name, it works successfully BUT no table shows up... where is it?
Second when I execute again I get an error
There is already an object named '##sp_MemberCertificates' in the database
I'm trying to fix this by using:
IF (SELECT object_id('TempDB..##Temp')) IS NOT NULL
BEGIN
DROP TABLE ##Temp
END
But I don't know how to use this exactly...
CREATE PROCEDURE ##sp_MemberCertificates (#MemberId int, #FromDate Varchar (30), #ToDate Varchar (30))
AS
SELECT Email,
CertificateNumber,
Mem_Name,
Mem_Address,
Mem_city,
Mem_state,
Mem_cellno,
Amount,
DateValid,
DateSent
--Use INTO ?? --
FROM UnitedDiningClub.dbo.UDC_Certificates
JOIN UnitedDiningClub.dbo.UDC_Member m
ON m.Mem_ID = UDC_Certificates.MemberId
JOIN UnitedDiningClub.dbo.UDClub_Client c
ON c.ClientId = UDC_Certificates.RestaurantId
WHERE MemberId = #MemberId
ORDER BY MemberId
EXEC ##sp_MemberCertificates #MemberId = '1', #FromDate = '2011-07-19 00:00:00.000', #ToDate = '2015-07-19 00:00:00.000'
go
Thanks for the help, please let me know if there more problems with the code, I am trying to learn.
use this to execute your stored procedure
rename your procedure to usp_MemberCertificates '##sp_MemberCertificates' is used for temp sp
remove exec statement from your procedure
use exec statement like this
EXEC usp_MemberCertificates 1, '2011-07-19 00:00:00.000', '2015-07-19 00:00:00.000'
you don't have to mention the variable name
moreover 1 is integer whereas you were sending a varchar type
also once you create a procedure you should add Alter instead of Create to so that it doesnt throw this error
There is already an object named '##sp_MemberCertificates' in the
database
You create global temporary stored procedure (using prefix ##). This stored procedure is visible from all the sessions in the server. The stored procedure is in Temp DB (as you already mentioned). So you can add DROP PROCEDURE, not drop table as in your example. Also you have to DROP ##sp_MemberCertificates, not ##Temp.
Second when creating procedure the script must finish with GO, but before you try to execute (EXEC ##sp_MemberCertificates #MemberId = '1', #FromDate = '2011-07-19 00:00:00.000' in your code). Also if you intend to use INTO (--Use INTO ?? -- in your code) you must drop table before that.

I am trying to run a query based on the results from a stored procedure

First, here is the code for sp_GetWorkQByUserName:
ALTER PROCEDURE [dbo].[sp_GetWorkQByUserName]
( #UserName varchar(50),
#StartDate datetime,
#EndDate datetime )
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT SpotId FROM tblSpotCount WHERE StoreNum = EXECUTE sp_GetUserLocationCodes(#UserName)
ORDER BY SpotDt ASC
END
I know my SELECT DISTINCT statement is wrong, but I wrote it like that to help show what I'm trying to do. I want to run this stored procedure based on the results from the sp_GetUserLocationCodes with a parameter of #UserName.
From what I can tell, my problem lies in how I'm calling sp_GetUserLocationCodes.
Question: how can I run a SELECT DISTINCT query on tblSpotCount.SpotId based on the results from the sp_GetUserLocationCodes stored procedure?
You cannot use a stored procedure directly in a query. You can, however, insert the results of a stored procedure into a temporary table and use that in your query:
CREATE TABLE #storeLocations
(
-- appropriate column names and data types go here
)
INSERT INTO #storeLocations (put column list here)
EXECUTE sp_GetUserLocationCodes(#UserName)
SELECT DISTINCT SpotId
FROM tblSpotCount
WHERE EXISTS (SELECT 1
FROM #storeLocations
WHERE #storeLocations.StoreNum = tblSpotCount.StoreNum)
ORDER BY SpotDt ASC
DROP TABLE #storeLocations

Select Values From SP And Temporary Tables

I have a Stored Procedure in MSSQL 2008, inside of this i've created a Temporary Table, and then i executed several inserts into the temporary Table.
How can i select all the columns of the Temporary Table outside the stored procedure? I Mean, i have this:
CREATE PROCEDURE [dbo].[LIST_CLIENTS]
CREATE TABLE #CLIENT(
--Varchar And Numeric Values goes here
)
/*Several Select's and Insert's against the Temporary Table*/
SELECT * FROM #CLIENT
END
In another Query i'm doing this:
sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO
SELECT *
INTO #CLIENT
FROM OPENROWSET
('SQLOLEDB','Server=(local);Uid=Cnx;pwd=Cnx;database=r8;Trusted_Connection=yes;
Integrated Security=SSPI',
'EXEC dbo.LIST_CLIENTS ''20110602'', NULL, NULL, NULL, NULL, NULL')
But i get this error:
Msg 208, Level 16, State 1, Procedure LIST_CLIENTS, Line 43
Invalid object name '#CLIENT'.
I've tried with Global Temporary Tables and It doesn't work.
I know that is the scope of the temporary table, but, how can i get the table outside the scope of the SP?
Thanks in advance
I think there is something deeper going on here.
One idea is to use a table variable inside the stored procedure instead of a #temp table (I have to assume you're using SQL Server 2005+ but it's always nice to state this up front). And use OPENQUERY instead of OPENROWSET. This works fine for me:
USE tempdb;
GO
CREATE PROCEDURE dbo.proc_x
AS
BEGIN
SET NOCOUNT ON;
DECLARE #x TABLE(id INT);
INSERT #x VALUES(1),(2);
SELECT * FROM #x;
END
GO
SELECT *
INTO #client
FROM OPENQUERY
(
[loopback linked server name],
'EXEC tempdb.dbo.proc_x'
) AS y;
SELECT * FROM #client;
DROP TABLE #client;
DROP PROCEDURE dbo.proc_x;
Another idea is that perhaps the error is occurring even without using SELECT INTO. Does the stored procedure reference the #CLIENT table in any dynamic SQL, for example? Does it work when you call it on its own or when you just say SELECT * FROM OPENROWSET instead of SELECT INTO? Obviously, if you are working with the #temp table in dynamic SQL you're going to have the same kind of scope issue working with a #table variable in dynamic SQL.
At the very least, name your outer #temp table something other than #CLIENT to avoid confusion - then at least nobody has to guess which #temp table is not being referenced correctly.
Since the global temp table failed, use a real table, run this when you start your create script and drop the temp table once you are done to make sure.
IF OBJECT_ID('dbo.temptable', 'U') IS NOT NULL
BEGIN
DROP TABLE dbo.temptable
END
CREATE TABLE dbo.temptable
( ... )
You need to run the two queries within the same connection and use a global temp table.
In SQL Server 2008 you can declare User-Defined Table Types which represent the definition of a table structure. Once created you can create table parameters within your procs and pass them a long and be able to access the table in other procs.
I guess the reason for such behavior is that when you call OPENROWSET from another server it firstly and separately requests the information about procedure output structure (METADATA). And the most interesting thing is that this output structure is taken from the first SELECT statement found in the procedure. Moreover, if the SELECT statement follows the IF-condition the METADATA request ignores this IF-condition, because there is no need to run the whole procedure - the first met SELECT statement is enough. (By the way, to switch off that behavior, you can include SET FMTONLY OFF in the beginning of your procedure, but this might increase the procedure execution time).
The conclusions:
— when the METADATA is being requested from a temp table (created in a procedure) it does not actually exists, because the METADATA request does not actually run the procedure and create the temp table.
— if a temp table can be replaced with a table variable it solves the problem
— if it is vital for the business to use temp table, the METADATA request can be fed with fake first SELECT statement, like:
declare #t table(ID int, Name varchar(15));
if (0 = 1) select ID, Name from #t; -- fake SELECT statement
create table #T (ID int, Name varchar(15));
select ID, Name from #T; -- real SELECT statement
— and one more thing is to use a common trick with FMTONLY (that is not my idea) :
declare #fmtonlyOn bit = 0;
if 1 = 0 set #fmtonlyOn = 1;
set fmtonly off;
create table #T (ID int, Name varchar(15));
if #fmtonlyOn = 1 set fmtonly on;
select ID, Name from #T;
The reason you're getting the error is because the temp table #Client was not declared before you ran the procedure to insert into it. If you declare the table, then execute the list proc and use direct insert -
INSERT INTO #Client
EXEC LIST_CLIENTS

How i can retrieve data from stored procedure in table format like normal query

I want to retrieve data from stored procedure in table format like normal sql query.
what i have to change?
my procedure is.....
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [dbo].[agg]
AS
DECLARE #stud int,
#lec int,
#dept varchar(50),
#sem int
select #stud=s.sem_no_stud,
#lec=sum(convert (int,sub.sub_lec)),#dept=d.dept_name,#sem=count(s.sem_id)
from sem_info s,sub_info sub,dept_info d,course_info co
where sub.sdept=d.dept_id and
s.sem_caurse_id=co.co_id and
sub.sub_sem_id=s.sem_id and co.co_id=149
group by d.dept_name,s.sem_id,s.sem_no_stud
return (#stud)
return(#lec)
exec agg;
The variables appear to serve no purpose. You can just SELECT directly. Additionally you need a go before your exec to avoid inadvertently creating a recursive procedure and you will be safer using explicit JOIN syntax as below to avoid inadvertent Cartesian joins.
ALTER PROCEDURE [dbo].[agg]
AS
SELECT s.sem_no_stud ,
SUM(CONVERT (INT,sub.sub_lec)),
d.dept_name ,
COUNT(s.sem_id)
FROM sem_info s
JOIN sub_info sub
ON sub.sub_sem_id =s.sem_id
JOIN dept_info d
ON sub.sdept =d.dept_id
JOIN course_info co
ON s.sem_caurse_id=co.co_id
WHERE co.co_id =149
GROUP BY d.dept_name,
s.sem_id ,
s.sem_no_stud
go
exec [dbo].[agg] ;
You just write a SELECT statement with the variables in like this:
SELECT #stud AS ColumnNameA, #lec AS ColumnNameB
However, something to point out is what if the query returns multiple rows? Assigning into variables like this will only return one of those records - the last records values to be assigned in to them will be returned.