How can create a table while Execute dynamic #Query - stored-procedures

I have a dynamic query in my sp which has different columns related to the inputs that user will enter. After that, In sp I want to join the result of it to the remaining part of sp. So I should have the table for join and as I mentioned I can not have static fields So my question is how can I drop table and create it any time run query instead of creating static table and each time truncate it and insert into it which is fixed.
for clearing my question I copy my sp's text maybe help!
ALTER PROC SP_DamageVasting (#BranchId int , #FromYear int , #ToYear int )
AS
BEGIN
DECLARE #Cols1 AS NVARCHAR(MAX)=''
DECLARE #Cols2 AS NVARCHAR(MAX)=''
DECLARE #Query1 AS NVARCHAR(MAX);
DECLARE #Query2 AS NVARCHAR(MAX);
WHILE (#FromYear <= #ToYear)
BEGIN
SET #Cols1 =#Cols1+'['+CONVERT (nchar(4),#FromYear)+'],'
SET #Cols2 =#Cols2 +'SUM(['+CONVERT (nchar(4),#FromYear)+']) AS ['+CONVERT
(nchar(4),#FromYear)+'],'
SET #FromYear=#FromYear+1
END
SELECT #Query1 ='SELECT PolicyId , BnIssueYear , BranchId , BranchName ,'+ LEFT(#Cols1
,LEN(#Cols1)-1)+
'FROM (SELECT PolicyId , LEFT( Hv.FVsodurDate, 4) AS BnSodurYear ,P.BranchCode AS BranchId,
L.Name AS BranchName ,
LEFT(HV.Date , 4) AS HvYear , SUM(HV.HVAmount) AS HvAmount
FROM DWHdb.amr.V_FactHV AS Hv
INNER JOIN DWHdb.cmn.DimLocationNode AS P (nolock) ON P.LocationId = Hv.FVBNIssueId AND
Hv.FVIssueDate BETWEEN P.Fromdate AND P.ToDate
INNER JOIN DWHdb.cmn.DimLocation AS L ON L.LocationId = P.BranchCode
WHERE Hv.FVIssueDate>''2010-01-01'' AND BranchCode = '+CONVERT (nchar(3),#BranchId)+'
GROUP BY
PolicyId ,
LEFT( Hv.FVIssueDate, 4) ,
P.BranchCode,
L.Name ,
LEFT(HV.Date , 4))AS A
PIVOT (SUM(HvAmount) FOR HvYear IN ('+ LEFT(#Cols1 ,LEN(#Cols1)-1)+')) AS V'
TRUNCATE TABLE [ApiFanavaranService].Bpmn.DamagePerYear --- *****Here I want to have
dynamic table and each time drop and create it *********
INSERT INTO [ApiFanavaranService].Bpmn.DamagePerYear
EXEC (#Query1);
SELECT #Query2='SELECT BNYear ,SUM(Prm) AS Prm,'+LEFT(#Cols2 ,LEN(#Cols2)-1)+'
FROM (
SELECT
BN.PolicyId ,
LN.BranchCode ,
LEFT(BN.FVIssueDate ,4) AS BNYear ,
SUM(BN.Prm ) AS Prm
FROM
DWHdb.amr.FactAmarBn AS BN INNER JOIN
DWHdb.cmn.DimLocationNode AS LN ON BN.FVIssueId = LN.LocationId AND
BN.FVIssueDate>=LN.FromDate AND BN.FVIssueDate<=LN.ToDate
WHERE BN.FVSodurDate >=''2010-01-01'' AND LN.BranchCode ='+CONVERT
(nchar(3),#BranchId)+'
GROUP BY
BN.PolicyId ,
LN.BranchCode,
LEFT(BN.FVIssueDate ,4)) AS A LEFT JOIN
ApiFanavaranService.Bpmn.DamagePerYear AS F ON
A.PolicyId=F.PolicyId AND A.BNYear=F.BnIssueYear
GROUP BY BNYear'
EXEC (#Query2);
END

I myself find the answer and it work correctly.
I just add the code bellow to my code I make the creation of table also dynamic query and run it sp_executesql.
I just want to help anybody who has the same issue as I do.
DECLARE #Col1 AS NVARCHAR(MAX)=''
DECLARE #Col2 AS NVARCHAR(MAX)=''
DECLARE #Col3 AS NVARCHAR(MAX)=''
DECLARE #Query1 AS NVARCHAR(MAX);
DECLARE #Query2 AS NVARCHAR(MAX);
DECLARE #Query3 AS NVARCHAR(MAX);
WHILE (#FromYear <= #ToYear)
BEGIN
SET #Col1 = #Col1+'['+CONVERT (nchar(4),#FromYear)+'],'
SET #Col2 = #Col2 +'SUM(['+CONVERT (nchar(4),#FromYear)+']) AS ['+CONVERT
(nchar(4),#FromYear)+'],'
SET #Col3 = #Col3 +'['+CONVERT (nchar(4),#FromYear)+'] decimal(38,6),'
SET #FromYear=#FromYear+1
END
DROP TABLE Bpmn.DamagePerYear
SET #Query3 = 'CREATE TABLE [ApiFanavaranService].Bpmn.DamagePerYear (
PolicyId int ,
BnIssueYear int,
BranchId int,
BranchName nchar(200) , '+
LEFT(#Col3 ,LEN(#Col3)-1)+')'
EXEC sp_executesql #Query3

Related

How do I modify a Stored Procedure to Join an additional table?

I have a fairly complex Stored Procedure that is joining several tables together, but I need yet another column called in from a table that is yet to be joined.
Here's the Stored Procedure as it stands:
CREATE PROCEDURE [rpt].[PlannerShipToLocations_ds1]
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql nvarchar(4000)
,#DateStart nvarchar(10) = '2015-01-01'
DECLARE #t TABLE (
[PCN] int
,[Part_Key] int
,[Customer_Address_No] int
PRIMARY KEY CLUSTERED (
[Part_Key]
,[Customer_Address_No]
,[PCN]
)
)
SET #sql =
'SELECT *
FROM OPENQUERY (PLEXRPTSVR,
''SELECT DISTINCT
s.[PCN]
,sl.[Part_Key]
,s.[Customer_Address_No]
FROM [Sales_v_Shipper_e] AS s
INNER JOIN [Sales_v_Shipper_Status_e] AS ss
ON s.[PCN] = ss.[PCN]
AND s.[Shipper_Status_Key] = ss.[Shipper_Status_Key]
INNER JOIN [Sales_v_Shipper_Line_e] AS sl
ON s.[PCN] = sl.[PCN]
AND s.[Shipper_Key] = sl.[Shipper_Key]
WHERE 1 = 1
AND ss.[Shipped] = 1
AND s.[Ship_Date] >= ''''' + #DateStart + '''''
;'')'
INSERT INTO #t
EXECUTE sp_executesql #sql
;WITH base AS (
SELECT DISTINCT u.[Last_Name] + ', ' + u.[First_Name] AS [Planner]
,c.[Customer_Code] AS [Customer Code]
,c.[Name] AS [Customer Name]
,a.[Customer_Address_Code] AS [Customer Address Code]
**/* xxx.[Country] AS [Country] */**
FROM [plx].[Part_v_Customer_Part_e] cp
INNER JOIN [plx].[Part_v_Part_e] p
ON cp.[Plexus_Customer_No] = p.[Plexus_Customer_No]
AND cp.[Part_Key] = p.[Part_Key]
INNER JOIN [plx].[Common_v_Customer_e] c
ON cp.[Plexus_Customer_No] = c.[Plexus_Customer_No]
AND cp.[Customer_No] = c.[Customer_No]
INNER JOIN [plx].[Plexus_Control_v_Plexus_User_e] u
ON p.[Plexus_Customer_No] = u.[Plexus_Customer_No]
AND p.[Planner] = u.[Plexus_User_No]
OUTER APPLY (
SELECT [Customer_Address_Code], **/*[Country]*/**
FROM [plx].[Common_v_Customer_Address_e] a
INNER JOIN #t t
ON a.[Plexus_Customer_No] = t.[PCN]
AND a.[Customer_Address_No] = t.[Customer_Address_No]
**/* INNER JOIN [plx].[Common_v_Country] xxx
ON a.[Country_Key] = xxx.[Country_Key] */**
WHERE a.[Plexus_Customer_No] = p.[Plexus_Customer_No]
AND a.[Customer_No] = c.[Customer_No]
AND t.[Part_Key] = p.[Part_Key]
AND a.[Ship_To] = 1
) a
**
/* INNER JOIN [plx].[Common_v_Country] xxx
ON a.[Country_Key] = xxx.[Country_Key] */
/*
OUTER APPLY (
SELECT [Country]
FROM [plx].[Common_v_Country] xxx
INNER JOIN #t t
ON a.[Country_Key] = xxx.[Country_Key]
WHERE a.[Plexus_Customer_No] = p.[Plexus_Customer_No]
AND a.[Customer_No] = c.[Customer_No]
AND t.[Part_Key] = p.[Part_Key]
AND a.[Ship_To] = 1
) xxx
*/**
WHERE 1 = 1
AND u.[Lockout] = 0
AND p.[Part_Status] IN ('Production', 'Production - Near EOP', 'Pre-Production')
AND cp.[Active] = 1
)
SELECT t1.[Planner]
,t1.[Customer Code]
,t1.[Customer Name]
,STUFF(
(SELECT
' | ' + t2.[Customer Address Code]
FROM base t2
WHERE t1.[Planner] = t2.[Planner]
and t1.[Customer Code] = t2.[Customer Code]
ORDER BY t2.[Customer Address Code]
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,3,'') AS [Customer Address Code(s)]
FROM base t1
GROUP BY t1.[Planner]
,t1.[Customer Code]
,t1.[Customer Name]
ORDER BY [Customer Code]
,[Planner]
,[Customer Address Code(s)]
END
GO
I've bolded the sections that are my best guesses about how to go about joining this additional table, I recognize that I wouldn't use all of them but I wanted to show my thoughts. To break it down:
1.) [plx].[Common_v_Customer_Address_e] a AND [plx].[Common_v_Country] xxx are the two tables I need in order to call [Country] out by name. I essentially need to add this as a column displayed on the report and eventually will need to sort on it as well (I'll probably add it to ORDER BY at the end).
2.) I'm not sure if I need to be joining [plx].[Common_v_Country] xxx within the OUTER APPLY or if it needs its own separate INNER JOIN or what. I've illustrated and commented out both here. So far everything I've tried results in "The multi-part identifier 'xxx.Country' could not be bound."
Thanks for the help.
I've tried modifying the OUTER APPLY to include the new table. I've tried creating my own new INNER JOIN. I've tried creating my own new OUTER APPLY.

why does Stored procedure not return the 'Out' parameter in bigquery?

I am writing below Stored Procedure in BigQuery but not sure where did I do wrong.
The 'Out' Parameter does not return anything.
Stored Procedure:
create procedure if not exists test.GetNumTherapistSessions(
in LastNamee string,
out NumSessione int64
)
begin
select count(s.SessionNum) as NumSession from test.Session s
inner join test.Therapist t on s.TherapistID=t.TherapistID
where t.LastName=LastNamee;
end
and Here is how I declare the output parameter and how to call it:
declare NumSession int64;
call test.GetNumTherapistSessions("Risk",NumSession);
Here is the output:
So far everything seems right, but when I select the NumSession, it returns Null:
select NumSession;
Output:
Try SET NumSessione = (select count...);
create procedure if not exists test.GetNumTherapistSessions(
in LastNamee string,
out NumSessione int64
)
begin
SET NumSessione = (
select count(s.SessionNum) as NumSession from test.Session s
inner join test.Therapist t on s.TherapistID=t.TherapistID
where t.LastName=LastNamee
);
end
As shown in this docs of bigquery Link you can use SET to assign any values you need to a specific Variables.
Note that bigquery don't have SELECT INTO statement inside procedure.
Examples:
SET (value1, value2, value3) = (SELECT AS STRUCT c1, c2, c3 FROM table_name WHERE condition)
From this answer:select-into-with-bigquery
Another Example:
UPDATE dataset.Inventory
SET quantity = quantity +
(SELECT quantity FROM dataset.NewArrivals
WHERE Inventory.product = NewArrivals.product),
supply_constrained = false
WHERE product IN (SELECT product FROM dataset.NewArrivals)
Another examples can be found here: Link

Any way to improve the performance of this store procedure?

Any way to improve the performance of this store procedure?
For example combining both updates clauses in a unique statement (T-SQL).
BonosConvenio and CON_Convenio are almost 5K rows.
create table #resultados (
monto_deuda float
,Cuenta float
,Rut varchar(10)
,CodCONVENIO varchar(4)
,CONVENIO varchar(50)
,Bono varchar(15)
,MontoBono float
,ApellDeudor varchar(100)
)
INSERT INTO #resultados(Cuenta,monto_deuda,Rut,CodCONVENIO,CONVENIO,Bono,MontoBono,ApellDeudor)
select ATC_CTA_Correlativo, monto_deuda, RutDeudor, CodCONVENIO,'','',0,''
from CartaCobProgramasCONVENIO
where Nomina = #Nomina
UPDATE #resultados
SET Bono=bc.Bono,
MontoBono=bc.Monto
FROM BonosCONVENIO bc
WHERE bc.ATC_CTA_Correlativo=#resultados.Cuenta;
UPDATE #resultados
SET ApellDeudor=upper(rtrim(ltrim(Paciente.PAC_PAC_Nombre))
FROM BD_ENTI_CORPORATIVA..ATC_Cuenta Cuenta, BD_ENTI_CORPORATIVA..PAC_Paciente Paciente
WHERE Cuenta.ATC_CTA_Correlativo=#resultados.Cuenta AND Paciente.PAC_PAC_Numero = Cuenta.PAC_PAC_Numero
UPDATE #resultados
SET CONVENIO=c.CON_CON_Descripcio
FROM BD_ENTI_CORPORATIVA..CON_Convenio c
WHERE c.CON_CON_Codigo =#resultados.CodCONVENIO
SELECT * FROM #resultados ORDER BY Cuenta,Bono
End
Try this:
SELECT
ccpc.ATC_CTA_Correlativo Cuenta
, ccpc.monto_deuda
, ccpc.RutDeudor Rut
, ccpc.CodCONVENIO
, c.CON_CON_Descripcio CONVENIO
, bc.Bono
, bc.Monto MontoBono
, UPPER(RTRIM(LTRIM(Paciente.PAC_PAC_Nombre))) ApellDeudor
FROM
CartaCobProgramasCONVENIO ccpc
INNER JOIN
BonosCONVENIO bc ON
ccpc.ATC_CTA_Correlativo = bc.ATC_CTA_Correlativo
INNER JOIN
BD_ENTI_CORPORATIVA..ATC_Cuenta Cuenta ON
ccpc.ATC_CTA_Correlativo = Cuenta.ATC_CTA_Correlativo
INNER JOIN
BD_ENTI_CORPORATIVA..PAC_Paciente Paciente ON
Cuenta.PAC_PAC_Numero = Paciente.PAC_PAC_Numero
INNER JOIN
BD_ENTI_CORPORATIVA..CON_Convenio c ON
c.CON_CON_Codigo = ccpc.CodCONVENIO
WHERE Nomina = #Nomina;
If you have duplicate records because of the joins, it's because there are multiple values in the tables. Your original query (using an update) would overwrite and only show the last row's value. To work around this, you would probably want to have a GROUP BY and MIN, MAX, SUM or whatever.

function or stored procedure for bulk insert in table by sets

how can i convert the following to teradata stored procedure or some function :
WHILE EXISTS (SELECT * FROM #temp_set1)
BEGIN
/*group of statemnts :delete insert etc
like */
INSERT INTO #temp_set
SELECT TOP 200 * FROM #temp_set1;
INSERT INTO Activepull
as select * from #temp_set1
and this should occur for each set of 200 untill all inserts
end;
There are more than 60000 rows in #temp_set1 so want to insert by sets.
Thanks.
Written on my phone, but I would use the over expression. It creates a kind of pseudo Identity column that you can then use to paginate. And you can even choose the order based on an order by clause.
Declare #IntervalSize int = 100
Declare #BeginSet int = 0,
#EndSet int = #IntervalSize
While #Counter < (Select Max(ROW_NUMBER() OVER (ORDER BY someColumn desc) From #temp_set1)
Begin
Insert Into #temp_set
Select *, Row_Number() Over (Order By someColumn desc) As MyIdentity
Where MyIdentity Between #BeginSet And #EndSet
Select #BeginSet = #BeginSet + #IntervalSize,
#EndSet = #EndSet + #IntervalSize
End

Sql Server queries optimization techniques

My Stored Procedure takes a very long time to execute.
Can anyone suggest me what I can do to speed up the stored procedure, apart from using some good practices for writing down the queries.
I've heard about creating indices, but I'm not sure what are they.
Please suggest all the best ways to speed up my queries.
Thanks
CREATE PROCEDURE [dbo].[usp_GetAlternates]
(
#NNumber CHAR(11) ,
#pid INT ,
#pbmid INT
)
AS
BEGIN
TRUNCATE TABLE TempTherapeuticAlt
INSERT INTO TempTherapeuticAlt
SELECT NULL AS MedicationID ,
PR.ePrescribingName AS MedicationName ,
U.Strength AS MedicationStrength ,
FRM.FormName AS MedicationForm ,
PR.DEAClassificationID AS DEASchedule ,
NULL AS NDCNumber
FROM Product PR
JOIN ( SELECT MP.MarketedProductID
FROM table2 TCTSP
JOIN table3 MP ON MP.SpecificProductID = TCTSP.SpecificProductID
JOIN ( SELECT TCTSP.TherapeuticConceptTreeID
FROM table3 MP
JOIN table2 TCTSP ON MP.SpecificProductID = TCTSP.SpecificProductID
JOIN ( SELECT
PR.MarketedProductID
FROM
table4 PA
JOIN Product PR ON PA.ProductID = PR.ProductID
WHERE
PA.NDC11 = #NNumber
) PAPA ON MP.MarketedProductID = PAPA.MarketedProductID
) xxx ON TCTSP.TherapeuticConceptTreeID = xxx.TherapeuticConceptTreeID
) MPI ON PR.MarketedProductID = MPI.MarketedProductID
JOIN ( SELECT P.ProductID ,
O.Strength ,
O.Unit
FROM Product AS P
INNER JOIN table3 AS M ON P.MarketedProductID = M.MarketedProductID
INNER JOIN table5 AS S ON M.SpecificProductID = S.SpecificProductID
LEFT OUTER JOIN table6 AS O ON S.SpecificProductID = O.SpecificProductID
GROUP BY P.ProductID ,
O.Strength ,
O.Unit
) U ON PR.ProductID = U.ProductID
JOIN ( SELECT PA.ProductID ,
S.ScriptFormID ,
F.Code AS NCPDPScriptFormCode ,
S.FormName
FROM table4 AS PA
INNER JOIN table7 AS S ON PA.NCPDPScriptFormCode = S.NCPDPScriptFormCode
INNER JOIN table8 AS F ON S.FormName = F.FormName
GROUP BY PA.ProductID ,
S.ScriptFormID ,
F.Code ,
S.FormName
) FRM ON PR.ProductID = FRM.ProductID
GROUP BY PR.ePrescribingName ,
U.Strength ,
FRM.FormName ,
PR.DEAClassificationID
ORDER BY pr.ePrescribingName
SELECT LL.ProductID AS MedicationID ,
temp.MedicationName ,
temp.MedicationStrength ,
temp.MedicationForm ,
temp.DEASchedule ,
temp.NDCNumber ,
fs.[ReturnFormulary] AS FormularyStatus ,
copay.CopaTier ,
copay.FirstCopayTerm ,
copay.FlatCopayAmount ,
copay.PercentageCopay
FROM TempTherapeuticAlt temp
OUTER APPLY ( SELECT TOP 1
ProductID
FROM Product
WHERE ePrescribingName = temp.MedicationName
) AS LL
OUTER APPLY function1(#pid, LL.ProductID, #pbmid) AS fs
OUTER APPLY function2(LL.ProductID, #pbmid) AS copay
ORDER BY LL.ProductID
TRUNCATE TABLE TempTherapeuticAlt
END
GO
Here are a few:
You should have indexes for every column in a WHERE clause. See
your SQL language for how to do it.
Learn how to EXPLAIN PLAN and see what's slow.
Stored procedure languages are functional, not set based. Use JOIN and don't fall into the (n+1) query/iteration trap.
Understand how using certain functions force you to TABLE SCAN in a WHERE clause.

Resources