SELECT Column AS #ParameterName in SQL Server stored procedure - sql

I have a stored procedure and I need to pass in a column alias as a parameter, how can I make this work?
This is the line of the stored procedure giving me trouble:
ManufacturerPriceListQty.Price As #PriceLevelAlias
and here is the stored procedure:
ALTER PROCEDURE [dbo].[Export_Products]
#PriceLevelAlias AS VARCHAR(25),
#PriceListCodes AS VARCHAR(250) --Exmaple: 'Des', 'Designer', 'Non-Stocking', 'NonStocking'
AS
BEGIN
SET NOCOUNT ON;
--PRINT #PriceListCodes
--SELECT * FROM dbo.Split(#PriceListCodes,',')
-- Insert statements for procedure here
SELECT
CAST(p.ManufacturerID as varchar(2))+'-'+p.ProductNumber AS ItemID,
SUBSTRING(p.ProductName,0,100) as ItemName,
p.ProductName AS [Description],
ManufacturerPriceListQty.Price As #PriceLevelAlias,
ManufacturerPriceListQty.Qty as OnHandQuantity,
ManufacturerPriceListQty.MultipleQty as OrderMinimumQuantity,
ManufacturerPriceListQty.MultipleQty as OrderMultipleQuantity,
Manufacturer.CompanyName AS CatalogName,
Manufacturer.CompanyName AS CatalogCode,
p.ProductNumber as UDF1,
CAST(p.ManufacturerID as varchar(2)) AS UDF2,
'%'+CAST(p.ProductID as varchar(10)) as UDF5,
CASE
WHEN P.Active ='1' THEN 'FALSE'
ELSE 'TRUE'
END AS IsDeleted,
#PriceLevelAlias AS PriceLevel,
ManufacturerPriceList.PriceListCode,
ManufacturerPriceListProduct.PriceListID
FROM
ManufacturerPriceListProduct
INNER JOIN
ManufacturerPriceList ON ManufacturerPriceListProduct.PriceListID = ManufacturerPriceList.PriceListID
INNER JOIN
Manufacturer ON ManufacturerPriceList.ManufacturerID = Manufacturer.ManufacturerID
INNER JOIN
ManufacturerPriceListQty ON ManufacturerPriceListProduct.PriceListProductID = ManufacturerPriceListQty.PriceListProductID
INNER JOIN
Product p ON ManufacturerPriceListProduct.ProductID = p.ProductID
WHERE
(Manufacturer.Active = 1)
AND p.Discontinued = 0
AND PriceListCode IN (SELECT * FROM dbo.Split(#PriceListCodes, ','))
END

instead of the direct script, try using the final select statement as Query string. Try the below :
ALTER PROCEDURE [dbo].[Export_Products]
#PriceLevelAlias AS VARCHAR(25),
#PriceListCodes AS VARCHAR(250) --Exmaple: 'Des', 'Designer', 'Non-Stocking', 'NonStocking'
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--PRINT #PriceListCodes
--SELECT * FROM dbo.Split(#PriceListCodes,',')
-- Insert statements for procedure here
DECLARE #v_Qry VARCHAR(MAX)
SELECT
#v_Qry = '
SELECT
CAST(p.ManufacturerID as varchar(2))+''-''+p.ProductNumber AS ItemID
,SUBSTRING(p.ProductName,0,100) as ItemName
,p.ProductName AS [Description]
,ManufacturerPriceListQty.Price As '+#PriceLevelAlias+'
,ManufacturerPriceListQty.Qty as OnHandQuantity
,ManufacturerPriceListQty.MultipleQty as OrderMinimumQuantity
,ManufacturerPriceListQty.MultipleQty as OrderMultipleQuantity
,Manufacturer.CompanyName AS CatalogName
,Manufacturer.CompanyName AS CatalogCode
,p.ProductNumber as UDF1
,CAST(p.ManufacturerID as varchar(2)) AS UDF2
,''%''+CAST(p.ProductID as varchar(10)) as UDF5
,CASE
WHEN P.Active =''1'' THEN ''FALSE''
ELSE ''TRUE''
END AS IsDeleted
,#PriceLevelAlias AS PriceLevel
,ManufacturerPriceList.PriceListCode
,ManufacturerPriceListProduct.PriceListID
FROM ManufacturerPriceListProduct INNER JOIN
ManufacturerPriceList ON ManufacturerPriceListProduct.PriceListID = ManufacturerPriceList.PriceListID INNER JOIN
Manufacturer ON ManufacturerPriceList.ManufacturerID = Manufacturer.ManufacturerID INNER JOIN
ManufacturerPriceListQty ON ManufacturerPriceListProduct.PriceListProductID = ManufacturerPriceListQty.PriceListProductID INNER JOIN
Product p ON ManufacturerPriceListProduct.ProductID = p.ProductID
WHERE (Manufacturer.Active = 1)
AND p.Discontinued=0
AND PriceListCode
IN(SELECT * FROM dbo.Split(#PriceListCodes,'',''))'
EXEC(#v_Qry)
END

It is not possible to set a column's alias dynamically. The only way to achieve this, is to create the full statement dynamically (there is an answer already).
With a closed set of possible values you could use a structure with IF to define your statement in all possible combinations.
The following might help you, if you have a closed set of values and the calling code knows, which column name is to be used.
As your SP is returning a result set, you might include the same value with all possible names. Look at this example
SELECT *
,type_desc AS Name1
,type_desc AS Name2
,type_desc AS Name3
--add all possible types here
FROM sys.objects
Which column you use after the call, will then be the decision of the calling code...

There were two other variables that need to be taken outside of the string:
`ALTER PROCEDURE [dbo].[Export_Products]
#PriceLevelAlias AS VARCHAR(25),
#PriceListCodes AS VARCHAR(250) --Exmaple: 'Des', 'Designer', 'Non-Stocking', 'NonStocking'
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--PRINT #PriceListCodes
--SELECT * FROM dbo.Split(#PriceListCodes,',')
-- Insert statements for procedure here
DECLARE #v_Qry VARCHAR(MAX)
SELECT
#v_Qry = '
SELECT
CAST(p.ManufacturerID as varchar(2))+''-''+p.ProductNumber AS ItemID
,SUBSTRING(p.ProductName,0,100) as ItemName
,p.ProductName AS [Description]
,ManufacturerPriceListQty.Price As '+#PriceLevelAlias+'
,ManufacturerPriceListQty.Qty as OnHandQuantity
,ManufacturerPriceListQty.MultipleQty as OrderMinimumQuantity
,ManufacturerPriceListQty.MultipleQty as OrderMultipleQuantity
,Manufacturer.CompanyName AS CatalogName
,Manufacturer.CompanyName AS CatalogCode
,p.ProductNumber as UDF1
,CAST(p.ManufacturerID as varchar(2)) AS UDF2
,''%''+CAST(p.ProductID as varchar(10)) as UDF5
,CASE
WHEN P.Active =''1'' THEN ''FALSE''
ELSE ''TRUE''
END AS IsDeleted
,''' + #PriceLevelAlias + ''' AS PriceLevel
,ManufacturerPriceList.PriceListCode
,ManufacturerPriceListProduct.PriceListID
FROM ManufacturerPriceListProduct INNER JOIN
ManufacturerPriceList ON ManufacturerPriceListProduct.PriceListID = ManufacturerPriceList.PriceListID INNER JOIN
Manufacturer ON ManufacturerPriceList.ManufacturerID = Manufacturer.ManufacturerID INNER JOIN
ManufacturerPriceListQty ON ManufacturerPriceListProduct.PriceListProductID = ManufacturerPriceListQty.PriceListProductID INNER JOIN
Product p ON ManufacturerPriceListProduct.ProductID = p.ProductID
WHERE (Manufacturer.Active = 1)
AND p.Discontinued=0
AND PriceListCode
IN(SELECT * FROM dbo.Split(''' + #PriceListCodes + ''','',''))'
EXEC(#v_Qry)
END`

Related

Replacing Is Null Or Exist Inner Query Logic to Reduce Stored Procedure Execution Time

My stored procedure is currently using Is Null Or Exist logic combined with an inner query to filter out the records. The stored procedure is converting multiple comma-separated input values to temp tables (in the production scenario, the input record count will be much higher). And the inner query is using these temp tables for filter conditions. Due to the concern over query execution time would like to change the existing inner-query with an alternate (like left join). But need to retain the same Is Null Or Exist logic. Any suggestions?
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
WHERE (#SelectedOfferes IS NULL
OR (EXISTS (SELECT 1 FROM #SelectedOfferes OFR
WHERE OFR.DiscountCode = P.DiscountCode)))
AND (#SelectedBrandCode IS NULL
OR (EXISTS (SELECT 1 FROM #BrandCode BC
WHERE BC.BrandCode = P.BrandCode)))
AND (#CategoryCode IS NULL
OR (EXISTS (SELECT 1 FROM #CategoryCode CAT
WHERE CAT.CategoryCode = P.CategoryCode)))
Dynamic SQL version
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
The below example should work the same as what you supplied but should be faster since it removes the ORs and the correlated subqueries from the WHERE clause. I'm not a fan of using dynamic SQL but sometimes it is the best way to get the job done. Maybe someone else can come up with a non-dynamic solution that works as well or better.
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
DECLARE #SQL NVarchar(4000);
SET #SQL = N'SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode'
IF #SelectedOfferes IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode';
IF #SelectedBrandCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode';
IF #CategoryCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode';
EXEC sys.sp_executesql #stmt = #SQL;
This method doesn't quite do what the OP wanted but is valid in many other cases
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
But either way the below change to your last query should help quite a bit. The IS NULL parts aren't needed since it is a LEFT JOIN and the table will be empty if the variable it is built with is NULL, so you get the same result with less work for the engine.
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
LEFT JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode
LEFT JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode
LEFT JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode

How to create procedure with multiple string select query in sql?

I want to create procedure with multiple string select query.I want to insert data to table variable and join that temp table with other table.
I don't want to create temp table as real tables. I want to insert data to memory temp table.
Here is my procedure,
CREATE PROCEDURE sp_TempBatch
AS
DECLARE #TempBatchSerial TABLE
(
ID int,
Name nvarchar(200),
StockType nvarchar(50),
ItemNo nvarchar(50)
)
DECLARE #TempQuery as nvarchar(MAX)='',
#VendorQuery as nvarchar(MAX)=''
BEGIN
SET #TempQuery='SELECT ID,Name,'
IF StockType = '1'
BEGIN
SET #TempQuery += ' ''Batch'' as StockType,'
END
ELSE
BEGIN
SET #TempQuery += ' ''Serial'' as StockType,'
END
SET #TempQuery += 'ItemNo INTO #TempBatchSerial
FROM Stock'
EXEC (#TempQuery)
SET #VendorQuery+=' SELECT #TempBatchSerial.* FROM #TempBatchSerial
INNER JOIN Vendor
ON #TempBatchSerial.ID = Vendor.ID
INNER JOIN Partner
ON Vendor.parentid = Partner.syskey'
EXEC (#VendorQuery)
END
When execute procedure show error message of Must declare the table variable "#TempBatchSerial"
You have to refer to #tempBatchSerial via an Alias
That's the only way #tempTables can be referred or linked to.
SELECT T.* FROM #TempBatchSerial T
INNER JOIN Vendor
ON T.ID = Vendor.ID
INNER JOIN Partner
ON Vendor.parentid = Partner.syskey
If that doesn't work you can try to put the #tempTable in the #vendorQuery text.

SELECT case using a variable which can be set based on a parameter

I'd like to select a particular value from a table while using an information from another database that is set based on a current database's value.
So a select case to find the operator code and set the DB path.. then use the same path and collate the result.
DECLARE #DB varchar (1000)
CASE
WHEN #Operator= 1 THEN SET #DB = '{SERVERNAME\ENTITY\DBNAME}'
WHEN #Operator= 2 THEN SET #DB = '{SERVERNAME2\ENTITY2\DBNAME2}'
WHEN #Operator= 3 THEN SET #DB = '{SERVERNAME3\ENTITY3\DBNAME3}'
Select transItem_item collate SQL_Latin1General_CI_AS
FROM Group_Transactions
INNER JOIN #DB.Table_Trans
ON (transItem.item_id collate SQL_Latin1General_CI-AS = Table_Trans.item_id)
Where ---Condition
Control flow method (likely to be the most efficient):
IF #Operator = 1
BEGIN
SELECT stuff
FROM Group_Transactions
INNER
JOIN "Server1\Instance1".Database1.Schema.Table_Trans
ON Group_Transactions... = Table_Trans...
WHERE things...
;
END
ELSE IF #Operator = 2
BEGIN
SELECT stuff
FROM Group_Transactions
INNER
JOIN "Server2\Instance2".Database2.Schema.Table_Trans
ON Group_Transactions... = Table_Trans...
WHERE things...
;
END
ELSE IF #Operator = 3
BEGIN
SELECT stuff
FROM Group_Transactions
INNER
JOIN "Server3\Instance3".Database3.Schema.Table_Trans
ON Group_Transactions... = Table_Trans...
WHERE things...
;
END
;
Single [conditional] query method:
SELECT Group_Transactions.stuff
, trans1.other_thing As other_thing1
, trans2.other_thing As other_thing2
, trans3.other_thing As other_thing3
, Coalesce(trans1.other_thing, trans2.other_thing, trans3.other_thing) As other_thing
FROM Group_Transactions
LEFT
JOIN "Server1\Instance1".Database1.Schema.Table_Trans As trans1
ON trans1... = Group_Transactions...
AND trans1.things...
AND #Operator = 1
LEFT
JOIN "Server2\Instance2".Database2.Schema.Table_Trans As trans2
ON trans2... = Group_Transactions...
AND trans2.things...
AND #Operator = 2
LEFT
JOIN "Server3\Instance3".Database3.Schema.Table_Trans As trans3
ON trans3... = Group_Transactions...
AND trans3.things...
AND #Operator = 3
;
If this is TSQL (I am guessing from your colation names) then you are best trying out OPENQUERY to run your join against another database server. If you are querying a database on the same server you could build your query up as a parameter and then run it using EXEC.
Gvee's Control Flow method may be a verbose, but it would work. You might want to create a look up table like my #tbl_Databases if you have a bunch of databases. Here's a dynamic SQL solution:
DECLARE #Operator INT = 1,
#DB VARCHAR(1000);
DECLARE #tbl_Databases TABLE (ID INT IDENTITY(1,1),DB VARCHAR(1000))
INSERT INTO #tbl_Databases(DB)
VALUES ('{SERVERNAME\ENTITY\DBNAME}'),('{SERVERNAME2\ENTITY2\DBNAME2}'),('{SERVERNAME3\ENTITY3\DBNAME3}');
SELECT #DB = DB
FROM #tbl_Databases
WHERE ID = #Operator
SELECT #DB
SELECT
(
'SELECT transItem_item COLLATE SQL_Latin1General_CI_AS
FROM Group_Transactions
INNER JOIN ' + #DB + '.dbo.Table_Trans
ON (transItem.item_id collate SQL_Latin1General_CI-AS = Table_Trans.item_id)
Where 1 = 1'
)

optimizing the code

I have written this code for small database but know the database size has increased,it is showing timeout error.plz help in optimizing it
Below is the code:-
IF OBJECT_ID('Temp_expo') is not null
begin
drop table Temp_expo
end
set #query3 = 'SELECT SPCT_ID_REL_LOW,SPCT_ID_REL_HIGH,ROW_NUMBER() over (order by PDBC_PFX) as TempId
INTO Temp_expo
FROM ['+ #FCTServer +'].['+#FCTDBName+'].dbo.CMC_SPCT_SUPP_CONV
where SPCT_ID_REL_LOW <> '''' and SPCT_ID_REL_HIGH <> '''''
exec (#query3)
Select #minCount= min(TempId) from Temp_expo
Select #maxCount= max(TempId) from Temp_expo
create table #ICD9SPCT
(
ICD9Code varchar(200)
}
while #minCount<=#maxCount
begin
select #low=SPCT_ID_REL_LOW,#high=SPCT_ID_REL_HIGH
from Temp_expo
where TempId=#minCount
group by SPCT_ID_REL_LOW,SPCT_ID_REL_HIGH
set #loworder = (select ISNULL(OrderId,0) from FCT_ICD9_Diag_ORDER where ICD9=#low)
set #highorder = (select ISNULL(OrderId,0) from FCT_ICD9_Diag_ORDER where ICD9=#high)
insert into #ICD9SPCT
select ICD9 from FCT_ICD9_Diag_ORDER ordert
left join #ICD9SPCT icdorder on ordert.ICD9 = icdorder.ICD9Code
where OrderId between #loworder and #highorder and icdorder.ICD9Code is null
set #minCount = #minCount+1;
end
If this is for SQL SERVER, there are some basic tips you can try:
USE: WITH (NOLOCK) after every select you use.
i.e.
select ICD9 from FCT_ICD9_Diag_ORDER ordert WITH (NOLOCK)
left join #ICD9SPCT icdorder on ordert.ICD9 = icdorder.ICD9Code
where OrderId between #loworder and #highorder and icdorder.ICD9Code is null
You can also try to change your temp tables to variable tables, by just changing the # for an # like :
create table #ICD9SPCT
(
ICD9Code varchar(200)
}
Still, the WHILE loop you are using may be the primary cause of your problem.

Handling muliple rows with insert trigger

I have a trigger on an orders table that inserts order details into the order_details table. This works when only one row is entered, but not when multiple rows are inserted at once. I have read multiple threads > on various sites about using a cursor, while statements, temp tables, etc. I have tried a few but no success. Any suggestions on the BEST/Easiest way to ensure I get all the detailed rows added when an order is placed.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[CreateOrderDetails]
ON [dbo].[Orders]
FOR INSERT
AS
declare #OrderStagingId uniqueidentifier
declare #OrderType as varchar(50)
declare #OrderID uniqueidentifier
declare #LocationID uniqueidentifier
declare #status as varchar (25)
declare #vendorid as uniqueidentifier
SELECT #OrderID = OrderID, #LocationID = LocationID,
#vendorid = vendorid, #OrderStagingId = OrderStagingId
FROM inserted
Begin
SET NOCOUNT ON;
-- Insert statements for trigger here
Insert into [Brain].dbo.[Order_Details]
SELECT
NEWID() AS OrderDetailId, #OrderID AS OrderId,
dbo.OrderStaging_Details.EcProductID,
dbo.OrderStaging_Details.Qty, dbo.OrderStaging_Details.Qty_Type,
dbo.OrderStaging_Details.Cost, dbo.OrderStaging_Details.Ext_Cost,
dbo.OrderStaging_Details.EnteredBy,
NULL AS ReceivedBy, NULL AS ReceivedDate, NULL AS ReceivedQty,
dbo.OrderStaging_Details.OrderNote, NULL AS ReceivedNote,
dbo.OrderStaging_Details.UpdatedBy, dbo.OrderStaging_Details.UpdateDate
FROM
dbo.Vendor_Assigned_Locations
INNER JOIN
dbo.Vendor_Contacts
INNER JOIN
dbo.Vendors
INNER JOIN
dbo.OrdersStaging
INNER JOIN
dbo.OrderStaging_Details ON dbo.OrdersStaging.OrderStagingID = dbo.OrderStaging_Details.OrderStagingID
ON dbo.Vendors.VendorID = dbo.OrderStaging_Details.VendorId
ON dbo.Vendor_Contacts.Vendor_ID = dbo.Vendors.VendorID
ON dbo.Vendor_Assigned_Locations.LocationID = dbo.OrdersStaging.LocationID
AND dbo.Vendor_Assigned_Locations.VCID = dbo.Vendor_Contacts.VCID
INNER JOIN
dbo.Orders ON dbo.OrdersStaging.OrderStagingID = dbo.Orders.OrderStagingID
AND dbo.Vendors.VendorID = dbo.Orders.VendorID
AND dbo.Vendor_Contacts.VCID = dbo.Orders.VendorContactID
AND dbo.OrdersStaging.LocationID = dbo.Orders.LocationID
LEFT OUTER JOIN
dbo.Order_Details ON dbo.Orders.OrderID = dbo.Order_Details.OrderID
WHERE
(dbo.OrderStaging_Details.OrderStagingID = #OrderStagingID)
AND (dbo.OrdersStaging.LocationID = #Locationid)
AND (dbo.Vendors.VendorID = #Vendorid)
AND (dbo.Order_Details.OrderID IS NULL)
end
This trigger is probably necessary to you
ALTER TRIGGER [dbo].[CreateOrderDetails] ON [dbo].[Orders]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for trigger here
INSERT INTO [Brain].dbo.[Order_Details]
SELECT
NEWID() AS OrderDetailId, i.OrderID AS OrderId,
dbo.OrderStaging_Details.EcProductID,
dbo.OrderStaging_Details.Qty, dbo.OrderStaging_Details.Qty_Type,
dbo.OrderStaging_Details.Cost, dbo.OrderStaging_Details.Ext_Cost,
dbo.OrderStaging_Details.EnteredBy,
NULL AS ReceivedBy, NULL AS ReceivedDate, NULL AS ReceivedQty,
dbo.OrderStaging_Details.OrderNote, NULL AS ReceivedNote,
dbo.OrderStaging_Details.UpdatedBy, dbo.OrderStaging_Details.UpdateDate
FROM
dbo.OrdersStaging
INNER JOIN
dbo.OrderStaging_Details ON dbo.OrdersStaging.OrderStagingID = dbo.OrderStaging_Details.OrderStagingID
INNER JOIN
dbo.Vendors ON dbo.Vendors.VendorID = dbo.OrderStaging_Details.VendorId
INNER JOIN
dbo.Vendor_Contacts ON dbo.Vendor_Contacts.Vendor_ID = dbo.Vendors.VendorID
INNER JOIN
dbo.Vendor_Assigned_Locations ON dbo.Vendor_Assigned_Locations.LocationID = dbo.OrdersStaging.LocationID
AND dbo.Vendor_Assigned_Locations.VCID = dbo.Vendor_Contacts.VCID
INNER JOIN
dbo.Orders ON dbo.OrdersStaging.OrderStagingID = dbo.Orders.OrderStagingID
AND dbo.Vendors.VendorID = dbo.Orders.VendorID
AND dbo.Vendor_Contacts.VCID = dbo.Orders.VendorContactID
AND dbo.OrdersStaging.LocationID = dbo.Orders.LocationID
INNER JOIN
inserted i ON dbo.Orders.OrderID = i.OrderID
END
The outer select statement where you are picking up #OrderID, #LocationID etc, is only picking the first row out of inserted which contains all the orders that are being inserted in the transaction that pulled the trigger.
Use insert into detail(...)
Select NewID(), Inserted.OrderID, ...
From Inserted
inner join ...
Where etc
instead.
It's because you're thinking about rows rather than columns. Dump the #variables, and join on inserted.