Pass multiple values as parameter into a stored procedure - sql

I have the stored procedure to which I pass the parameters. These parameters are indicated by another tool. One of the parameter has a list of entities like C200, C010 etc.
But the requirement is that the person who will run the stored procedure from another tool (Fluence) should be able to call by each entity but also to retrieve the data related to all the entities.
I have the SQL code shown here, which perfectly works if you choose one entity at a time. In the Where clause, I filter it based on the #Entitygroup which is Declared. From another tool to fetch the all the Entity is passed at Total_group parameter name.
ALTER PROCEDURE [DW].[SP_Fetch_Data]
#par_FiscalCalendarYear varchar(10),
#par_Entity AS varchar (10)
AS
BEGIN
/*
BALANCE ACCOUNTS
*/
DECLARE #FiscalCalendarYear int = SUBSTRING(#par_FiscalCalendarYear,1,4) /* 2022 */
, #FiscalCalendarMonth int = SUBSTRING (#par_FiscalCalendarYear,7,10) /* 11 */;
DECLARE #FiscalCalendarPeriod int = #FiscalCalendarYear * 100 + #FiscalCalendarMonth
DECLARE #Entitygroup varchar = #par_Entity
SELECT UPPER([GeneralJournalEntry].SubledgerVoucherDataAreaId) as [Entity]
, CONCAT(#FiscalCalendarYear, ' P', #FiscalCalendarMonth) as [Date]
, ISNULL(ConsolidationMainAccount, '') as [Account]
, [GeneralJournalAccountEntry].TransactionCurrencyCode as [Currency]
, SUM([GeneralJournalAccountEntry].TransactionCurrencyAmount) as [Amount]
, 'Import' as [Audit]
, 'TCUR' as [DataView]
, ISNULL([CostCenter].[GroupDimension], 'No Costcenter') as [CostCenter]
, 'No Group' as [Group]
, ISNULL([Intercompany].[DisplayValue], 'No Intercompany') as [Intercompany]
, 'Closing' as [Movement]
, ISNULL([ProductCategory].[GroupDimension], 'No ProductCategory') as [ProductCategory]
, ISNULL([Region].[GroupDimension], 'No Region') as [Region]
, ISNULL([SalesChannel].[GroupDimension], 'No SalesChannel') as [SalesChannel]
, 'Actual' as [Scenario]
FROM [D365].[GeneralJournalAccountEntry]
LEFT JOIN [D365].[GeneralJournalEntry] ON [GeneralJournalAccountEntry].GENERALJOURNALENTRY = [GeneralJournalEntry].[RECID]
AND [GeneralJournalAccountEntry].[PARTITION] = [GeneralJournalEntry].[PARTITION]
LEFT JOIN [D365].[FiscalCalendarPeriod] ON [GeneralJournalEntry].FiscalCalendarPeriod = FiscalCalendarPeriod.FiscalCalendarPeriod
LEFT JOIN [DW].[MainAccounts] ON [GeneralJournalAccountEntry].MainAccount = [MainAccounts].[RECID]
LEFT JOIN [DW].[Intercompany] ON [GeneralJournalAccountEntry].[RECID] = [Intercompany].[RECID]
LEFT JOIN [DW].[ProductCategory] ON [GeneralJournalAccountEntry].[RECID] = [ProductCategory].[RECID]
LEFT JOIN [DW].[Region] ON [GeneralJournalAccountEntry].[RECID] = [Region].[RECID]
LEFT JOIN [DW].[SalesChannel] ON [GeneralJournalAccountEntry].[RECID] = [SalesChannel].[RECID]
LEFT JOIN [DW].[CostCenter] ON [GeneralJournalAccountEntry].[RECID] = [CostCenter].[RECID]
WHERE [EnumItemName] IN ('Revenue', 'Expense', 'BalanceSheet', 'Asset', 'Liability')
AND [FiscalCalendarPeriod].FiscalCalendarPeriodInt <= #FiscalCalendarPeriod
AND [GeneralJournalEntry].SubledgerVoucherDataAreaId <= #Entitygroup
GROUP BY UPPER([GeneralJournalEntry].SubledgerVoucherDataAreaId)
, ISNULL(ConsolidationMainAccount, '')
, [GeneralJournalAccountEntry].TransactionCurrencyCode
, ISNULL([CostCenter].[GroupDimension], 'No Costcenter')
, ISNULL([Intercompany].[DisplayValue], 'No Intercompany')
, ISNULL([ProductCategory].[GroupDimension], 'No ProductCategory')
, ISNULL([Region].[GroupDimension], 'No Region')
, ISNULL([SalesChannel].[GroupDimension], 'No SalesChannel')

(would be a mess as a comment)
Do you mean if #par_entity is not null and has a value other than '' then use that else go on as if it is not there at all? Then you can change your code:
DECLARE #Entitygroup varchar = #par_Entity
To:
DECLARE #Entitygroup varchar = case
when #par_Entity is not null then #par_Entity
else ''
end;
And:
AND [GeneralJournalEntry].SubledgerVoucherDataAreaId <= #Entitygroup
To:
AND (#Entitygroup = '' OR [GeneralJournalEntry].SubledgerVoucherDataAreaId <= #Entitygroup)
PS: Performance wise it wouldn't be optimal.
EDIT: You might also set it to the possible max value when it is not passed. ie:
DECLARE #Entitygroup varchar = case
when #par_Entity is null or #par_entity = '' then 'zzzzzz'
else #par_Entity
end;
AND [GeneralJournalEntry].SubledgerVoucherDataAreaId <= #Entitygroup

Related

Creating a decision table with accompanied procedure in SQL Server

I'm trying to think of the best way to write a procedure to evaluate a decision table in SQL Server.
The way I've begun doing it (see VERY simplified example below) would work fine except for the rows where that particular parameter doesn't matter. So, any one claim could fit the scenario in Row 4, provided it's of the type medical.The query, having found a match doesn't even evaluate the other rows. Is there a better way to do this?
I was thinking I could rank the rows of the table from most complicated scenario to least and then select the top row that fits, and that'd probably work, but in future, many more rows will be added to the table and each one would require an analysis of where it would fall in the table. Some situations might even conflict.
I want the best match for the scenario.
I currently have something that does something like this:
create table TTable( RowID varchar(max)
, ClaimType varchar(max)
, Insurance varchar(max)
, Eligibilty varchar(max)
, Result varchar(max)
, Assignment varchar(max)
, Admission varchar(max))
Insert into TTable (RowID, ClaimType, Insurance, Eligibility, Result ,Assignment, Admission)
values ('1' , 'Medical' , 'Insured' , 'Eligible' , 'Approval', 'AssignNurse' , 'Admit')
,('2' , 'Medical' , 'Uninsured' , 'N/A' , 'Denial' , 'N/A' ,'N/A')
,('3' , 'Medical' , 'N/A' , 'IncomeEligible' , 'Pend' , 'AssignReviewer' , 'Pend')
,('4' ,' Medical' , 'N/A' , 'N/A' , 'Pend' , 'Pend' , 'Pend')
create procedure getdecision( #ClaimID uniqueidentifier)
declare #Type
declare #Insurance
declare #Eligibility
Select #Type = Type
From claims
where claimid = #ClaimID
select #Insurance = Insurance
#Eligibility = Eligibility
from MemberInsurance
where membemberid = (select memberid from claims where claimid = #claimid)
select RowID,
Result,
Assignment,
Admission
From ttable t
WHERE #Type = ClaimType
and Case when t.Insurance = 'N/A'
then #Type
Else t.ClaimType
End
and Case when t.Eligible = 'N/A'
then #Eligibility
else t.Eligibilty
end

SQL, keep NULL instead of 0 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
i have a sql stored procedure that for some strange reason return 0 from a user-define-function even if this return a null value.
And more strange, if i moove only this part of stored procedure to a new query, this return correctly NULL, so i cant reproduce it
incriminated column is Abbattimento and the user function is [FN_Abbattimento_Copertura_Processo], linked in this way:
OUTER APPLY dbo.FN_Abbattimento_Copertura_Processo(Kint_TP006_IdAttivita,#AnnoRiferimento, IdLiv4, SPD.Ktyi_TP001_IdSocieta, Ktyi_TP058_IdSocietaService, tyi_TP058_Copertura, 2) [acp]
instead if i add
(Select * FROM dbo.FN_Abbattimento_Copertura_Processo(...)) AS Abbattimento
i get NULL VALUE, so the problem seem the call to function with apply
this is the entire store procedure:
ALTER PROCEDURE [dbo].EXT_Pian_DettaglioProcessi
#AnnoRiferimento SMALLINT = NULL
, #IdSocieta SMALLINT = NULL
, #IDAreaIncaricata SMALLINT = NULL
, #IDAreaCoinvolta SMALLINT = NULL
, #Ufficiale BIT = 0
, #Virtuali BIT = 0
AS
BEGIN
DECLARE #VirtualiIntero AS TINYINT
SET #VirtualiIntero =
CASE #Virtuali
WHEN 0 THEN 2
ELSE 0
END
--IF #IdSocieta = 0
-- SET #IdSocieta = NULL
--print #Virtuali
SELECT
SA.nvc_TP001_Societa AS Societa
, Kint_TP006_IdAttivita AS IdAttivita
, nvc_TP006_Attivita AS Attivita
, AreaIncaricata
, CONVERT(NVARCHAR(10), DataPianificata.InizioValStatus, 103) AS DataPianificazione
, StatusAttuale.DescrizioneStatus AS StatusAttuale
, CONVERT(NVARCHAR(10), StatusAttuale.InizioValStatus, 103) AS Dal
--, IdLiv2 AS IdProcessoLivello2
, Liv2 AS ProcessoLivello2
, IdLiv4 AS IdProcessoLivello4
, Liv4 AS ProcessoLivello4
, SPD.nvc_TP001_Societa AS SocietaProcesso
, SPS.nvc_TP001_SocietaAbbreviata AS SocietaServiceProcesso
, tyi_TP058_Copertura AS Copertura
, ksin_TP058_Anno AS AnnoInizioCopertura
--, CASE Abbattimento
-- WHEN 0 THEN NULL
-- ELSE Abbattimento
-- END AS Abbattimento
, Abbattimento
, TipoCopertura
, ISNULL(CP.CoperturaOverride, 0) + ISNULL(CP.CoperturaAttConRating, 0) AS CoperturaComplessivaProcesso
FROM
-- faccio una distinct per non avere duplicati per area e perimetro
-- non lo faccio nella select iniziale perchè altrimenti dovrei selezionare anche i campi usati solo per ordinamento
(SELECT DISTINCT
Kint_TP013_IdAttivita
, Ksin_TP013_AnnoRifPian
, Ktyi_TP013_ProgressivoPian
FROM Q_TP013_Pianificazione
WHERE
(ISNULL(#IDAreaIncaricata, #IDAreaCoinvolta) IS NULL
OR
Ksin_TP013_IdArea IN (SELECT idarea FROM dbo.FN_StrutturaAree(ISNULL(#IDAreaIncaricata, #IDAreaCoinvolta)))
)) AS Pian
INNER JOIN dbo.[FN_DettaglioPianificazione](#AnnoRiferimento, #Ufficiale) AS FiltroPianificazione
ON IdAttivita = Kint_TP013_IdAttivita
AND Progressivo = Ktyi_TP013_ProgressivoPian
INNER JOIN Q_TP006_Attivita
ON Kint_TP006_IdAttivita = Kint_TP013_IdAttivita
INNER JOIN TP001_Societa AS SA
ON SA.Ktyi_TP001_IdSocieta = tyi_TP006_IdSocieta
INNER JOIN
(SELECT
nvc_TP003_Area AS AreaIncaricata
, Kint_TP024_IdAttivita
FROM
Q_TP024_LinkAttivitaArea
INNER JOIN TP003_Area
ON Ksin_TP003_IdArea = Ksin_TP024_IdArea
WHERE
tyi_TP024_IdTipoLinkAttivitaArea = 1
AND Ksin_TP024_IdArea = COALESCE(#IDAreaIncaricata, Ksin_TP024_IdArea)
) AS AI
ON Kint_TP024_IdAttivita = Kint_TP006_IdAttivita
INNER JOIN dbo.FN_CoperturaProcessiAttivita(#AnnoRiferimento,0, #VirtualiIntero,0)
ON Kint_TP058_IdAttivita = Kint_TP006_IdAttivita
LEFT OUTER JOIN dbo.[FN_StrutturaProcessi](GETDATE())
ON IdLiv4 = Ksin_TP058_IdProcesso
LEFT OUTER JOIN TP001_Societa SPD
ON SPD.Ktyi_TP001_IdSocieta = Ktyi_TP058_IdSocieta
LEFT OUTER JOIN TP001_Societa SPS
ON SPS.Ktyi_TP001_IdSocieta = Ktyi_TP058_IdSocietaService
OUTER APPLY dbo.FN_DataStatusAttivita(Kint_TP006_IdAttivita,1) AS DataPianificata
OUTER APPLY dbo.FN_Status_Attivita_Periodo(GETDATE(), Kint_TP006_IdAttivita, null, null) AS StatusAttuale
OUTER APPLY dbo.FN_Abbattimento_Copertura_Processo(Kint_TP006_IdAttivita,#AnnoRiferimento, IdLiv4, SPD.Ktyi_TP001_IdSocieta, Ktyi_TP058_IdSocietaService, tyi_TP058_Copertura, 2) [acp]
OUTER APPLY dbo.FN_CoperturaProcesso(IdLiv4, SPD.Ktyi_TP001_IdSocieta, SPS.Ktyi_TP001_IdSocieta, #AnnoRiferimento) AS CP
WHERE
Ksin_TP013_AnnoRifPian = #AnnoRiferimento
--and IdAttivita = 12331
ORDER BY
Societa
, IdAttivita
, Ord1
, Ord2
, Ord3
, Ord4
And this is user-function that calculate Abbattimento:
ALTER FUNCTION [dbo].[FN_Abbattimento_Copertura_Processo]
(
-- Add the parameters for the function here
-- Add the parameters for the function here
#idAttivita int,
#anno smallint = 0,
#idProcesso smallint = 0,
#idSocieta tinyint = 0,
#idSocietaService tinyint = 0,
#copertura tinyint = 0,
#tipoAbbattimento TINYINT = 1 --1 Dalla prima presente, 2 dalla precedente
)
RETURNS TABLE
AS
RETURN
(
SELECT
CASE
WHEN #tipoAbbattimento = 1 THEN
(SELECT TOP 1 (CAST(tyi_TP058_Copertura AS SMALLINT) - #copertura)
FROM dbo.Q_TP058_LinkAttivitaLinkProcessoSocieta
WHERE Kint_TP058_IdAttivita = #idAttivita
AND Ksin_TP058_Anno between #anno-5 and #anno
AND Ksin_TP058_IdProcesso = #idProcesso
AND Ktyi_TP058_IdSocieta = #idSocieta
AND Ktyi_TP058_IdSocietaService = #idSocietaService
ORDER BY Ksin_TP058_Anno)
WHEN #tipoAbbattimento = 2 THEN
(SELECT TOP 1 (CAST(tyi_TP058_Copertura AS SMALLINT) - #copertura)
FROM dbo.Q_TP058_LinkAttivitaLinkProcessoSocieta
WHERE Kint_TP058_IdAttivita = #idAttivita
AND Ksin_TP058_Anno between #anno-5 and #anno-1
AND Ksin_TP058_IdProcesso = #idProcesso
AND Ktyi_TP058_IdSocieta = #idSocieta
AND Ktyi_TP058_IdSocietaService = #idSocietaService
ORDER BY Ksin_TP058_Anno DESC)
END AS Abbattimento
)
as you can see in comment now i have a case to convert back 0 to NULL, but honestly i don't like much this solution.
can you help me in finding the cause?
I've not read your query, but maybe will help for you NULLIFin following:
NULLIF(col,0)
It will return NULL if your column equals to 0

Msg 102, Level 15, State 1, Line 24 Incorrect syntax near '.'

All... based on another question I've posted here recently, I built this stored procedure, but when executed, I receive the error in the title.
As you can see, I tried to remove any aliases, but it didn't matter. Not sure how to use PRINT to see the issue on this either. Of course the isolated SELECT statement works on its own.
I can even pull results from my temp table after the error appears. So is it a problem in this script or the results? Appreciate your assistance. I also only used the WHERE statement to limit the test results.
ALTER PROC ap_vhdr_test AS
SET NOCOUNT ON
IF OBJECT_ID('temp.dbo.#ap_vend_det') is NOT NULL
DROP TABLE #ap_vend_det;
CREATE TABLE #ap_vend_det
(db_name varchar(32)
, vendor_name varchar(40)
, vendor_code varchar(12)
, voucher_no varchar(16)
, invoice_num varchar(16)
, inv_date varchar(16)
, due_date varchar(16)
, apply_date varchar(16)
, total float
, line_desc varchar(40)
, company_id smallint
, gl_num varchar(32)
, acct_site varchar(32)
, sort_code varchar(32)
, nat_gl varchar(32)
, gl_desc varchar(40)
, category nvarchar(510)
, sub_category nvarchar(510)
, po_num varchar(16)
, vendor_class varchar(8)
)
INSERT INTO #ap_vend_det
EXEC sp_MSforeachdb N'IF ''?'' NOT IN ( ''model'',''tempdb'',''master'',''msdb'')
BEGIN SELECT DISTINCT db_name = ''?''
, amaster.addr1 --as vendor_name
, amaster.vendor_code --as vendor_code
, apdet.trx_ctrl_num --as voucher_no
, aphdr.doc_ctrl_num --as invoice_num
, CONVERT(varchar(16),dateadd(dd,(aphdr.date_doc - 639906),''1/1/1753''),101) --as inv_date
, CONVERT(varchar(16),dateadd(dd,(aphdr.date_due - 639906),''1/1/1753''),101) --as due_date
, CONVERT(varchar(16),dateadd(dd,(aphdr.date_applied - 639906),''1/1/1753''),101) --as apply_date
, aphdr.amt_net --as total
, aphdr.doc_desc --as line_desc
, gldet.company_id --as company_id
, gldet.account_code --as gl_num
, gldet.seg2_code --as acct_site
, gldet.seg3_code --as sort_code
, gldet.seg1_code --as nat_gl
, gldet.description --as gl_desc
, ap_coa.group_header --as category
, ap_coa.group_label --as sub_category
, apdet.po_ctrl_num --as po_num
, apvend.vend_class_code --as vendor_class
FROM ?.dbo.amaster --amaster
JOIN ?.dbo.aphdr --aphdr --**
ON amaster.vendor_code = aphdr.vendor_code
AND amaster.pay_to_code = aphdr.pay_to_code
JOIN ?.dbo.apdet --apdet
ON aphdr.trx_ctrl_num = apdet.trx_ctrl_num
JOIN ?.dbo.gldet --gldet
ON aphdr.journal_ctrl_num = gldet.journal_ctrl_num
JOIN ?.dbo.glt --glt
ON gldet.journal_ctrl_num = glt.journal_ctrl_num
JOIN ?.dbo.apvend --apvend
ON amaster.vendor_code = apvend.vendor_code
JOIN reps.dbo.ap_coa --ap_coa
ON gldet.seg1_code = ap_coa.acct_code
WHERE aphdr.date_applied >= ''734785''
END';
SELECT * FROM #ap_vend_det;
This will fail if you have database names that have spaces or other characters in them. You need to enclose them in square brackets, e.g.
FROM [?].dbo.amaster --amaster
Not only that, because you are using 3 part names, you also need to alias the tables in the FROM clause.
FROM [?].dbo.amaster amaster
JOIN [?].dbo.aphdr aphdr --**
ON amaster.vendor_code = aphdr.vendor_code
AND amaster.pay_to_code = aphdr.pay_to_code
JOIN [?].dbo.apdet apdet
ON aphdr.trx_ctrl_num = apdet.trx_ctrl_num
JOIN [?].dbo.gldet gldet
ON aphdr.journal_ctrl_num = gldet.journal_ctrl_num
JOIN [?].dbo.glt glt
ON gldet.journal_ctrl_num = glt.journal_ctrl_num
JOIN [?].dbo.apvend apvend
ON amaster.vendor_code = apvend.vendor_code
JOIN reps.dbo.ap_coa ap_coa
ON gldet.seg1_code = ap_coa.acct_code
WHERE aphdr.date_applied >= ''734785''

An expression of non-boolean type specified in a context where a condition is expected, near... TABLE

What I am trying to do is based on the company_id (#company_id) which has a corresponding database name (#db_name), trying to pull data based on those variables. I have over 30 tables and need to view data based on which company_id(s) are selected.
i.e. EXEC journal_entries_by_dbase;1'1'
ALTER PROC esh_journal_entries_by_dbase
(#company_id varchar(2))
AS
-------------------------------------------------------
BEGIN
CREATE TABLE ##journal_dbase
(company_id varchar(8)
, journal_description varchar(255)
, journal_type varchar(8)
, date_entered varchar(10)
, date_applied varchar(10)
, date_posted varchar(10)
, hold_flag varchar(8)
, reversing_flag varchar(9)
, intercompany_flag varchar(8)
, domain_username varchar(255)
, posted_flag varchar(8)
, multi_currency_flag varchar(8)
, home_credit decimal(20,2)
, home_debit decimal(20,2))
;
-------------------------------------------------------
DECLARE --#company_id varchar(8)
#db_name varchar(32)
, #sql varchar(8000)
, #drop_table varchar(200)
;
-------------------------------------------------------
SET #db_name = 'select db_name from contrl.dbo.company where company_id = 1' --#company_id';
-------------------------------------------------------
SET #sql =
'INSERT INTO ##journal_dbase
SELECT '+#company_id+'
, trx.journal_description as [Description]
, trx.journal_type as [Journal Code]
, convert(varchar(12),dateadd(dd,(trx.date_entered - 639906),''1/1/1753''),101) as [Entry Date]
, convert(varchar(12),dateadd(dd,(trx.date_applied - 639906),''1/1/1753''),101) as [Apply Date]
, convert(varchar(12),dateadd(dd,(trx.date_posted - 639906),''1/1/1753''),101) as [Post Date]
--, trx.date_entered as [Entry Date]
--, trx.date_applied as [Apply Date]
--, trx.date_posted as [Post Date]
, [Hold] = CASE trx.hold_flag
WHEN 0 THEN ''No''
WHEN 1 THEN ''Yes''
END --as hold
, [Trans Flag] = CASE trx.reversing_flag
WHEN 0 THEN ''Standard''
WHEN 1 THEN ''Reversing''
END --as trans_flag
, [InterCo] = CASE trx.intercompany_flag
WHEN 0 THEN ''No''
WHEN 1 THEN ''Yes''
END
, CASE WHEN e.domain_username NOT LIKE ''%\%''
THEN e.domain_username
ELSE SUBSTRING(e.domain_username,5,20) --SELECT DISTINCT domain_username FROM ECTRL..smusers
END AS [User Name]
, [Posted Flag] = CASE trx.posted_flag
WHEN 0 THEN ''No''
WHEN 1 THEN ''Yes''
END
, trx.source_company_code as [Org]
--, SUM(bal.home_credit) as [Total Home Credit]
--, SUM(bal.home_debit) as [Total Home Debit]
, bal.home_credit as [Total Home Credit]
, bal.home_debit as [Total Home Debit]
FROM '+#db_name+'.dbo.trx trx
LEFT OUTER JOIN '+#db_name+'.dbo.trxdet trxdet
ON trx.journal_ctrl_num = trxdet.journal_ctrl_num
LEFT OUTER JOIN '+#db_name+'.dbo.bal bal
ON trxdet.account_code = bal.account_code
--LEFT OUTER JOIN con.dbo.users e
-- ON trx.user_id = e.user_id
--WHERE trx.date_posted > 0
-- AND trx.date_applied >= ''734503''
-- AND trx.date_applied <= ''734710'''
;
-------------------------------------------------------
SET #company_id = 'select company_id from ewcomp' --where db_name in (#db_name)
-------------------------------------------------------
EXEC (#sql);
-------------------------------------------------------
SELECT * FROM ##journal_dbase;
THis is returning An expression of non-boolean type specified in a context where a condition is expected, near bal and trx and trxdet.
My problem was that I was trying to reference internally to the company table to get the db_name, when I needed to JOIN on it to the sys.databases. I removed the SET #company_id and just used the following for the #db_name. It works.
SELECT #db_name = name
FROM sys.databases
JOIN contrl.dbo.company
ON sys.databases.name = contrl.dbo.company.db_name
WHERE contrl.dbo.company.company_id in (#company_id)
You are putting the SQL queries in the variables for the company and the database name. I think that you want to query the tables for the values:
SET #company = (SELECT company FROM contrl.dbo.company)
SET #db_name = (SELECT db_name FROM contrl.dbo.company WHERE company = #company)
Or simply:
SELECT #company = company FROM contrl.dbo.company
SELECT #db_name = db_name FROM contrl.dbo.company WHERE company = #company
Edit:
With your updated code; change this:
SET #db_name = 'select db_name from contrl.dbo.company where company_id = 1'
to
SELECT #db_name = db_name from contrl.dbo.company where company_id = 1
or with the #CompnayId variable:
SELECT #db_name = db_name from contrl.dbo.company where company_id = cast(#CompanyId as int)

How to insert unique value into non-identity field

I'm trying to do an insert into an established table which has a primary key fields and another field (call it field1) that is unique (this other unique field has a unique constraint preventing my inserts). Field1 is not an identity field, so it does NOT autonumber. Unfortunately I can't change the table. Existing inserts are made using code to increment and all involve looping/cursors. Something like SELECT MAX(field1) + 1
So, is there anyway to do this insert without looping/cursor? This field means nothing to me, but there are already 500,000+ records using their silly numbering scheme, so I must respect that.
This is simplified (ReceiptNumber is the field I want to insert unique), but:
SET XACT_ABORT ON
Begin Transaction TransMain
Declare #nvErrMsg nvarchar(4000)
--Insert inventory receipts
Insert Into Avanti_InventoryReceipts (
ReceiptNumber , ItemNumber , ReceiptDate , OrderNumber , JobNumber , Supplier ,
LineNumber , MultiLineNumber , [Status] , QtyOrdered , QtyReceived , QtyToReceive ,
QtyBackOrdered , Cost , Wholesale , LastCost , QtyToInvoice , QtyUsed ,
ReferenceNumber , [Description] , SupplierType , Processed , DateExpected , DateReceived ,
AccountNumber , Reference2 , EmployeeCode , ExtraCode , Location , RollNumber ,
QtyIssues , Notes , NumPackages , BundleSize , ConsignmentUnitPrice , RecFromProduction ,
QtyCommitted )
SELECT ( SELECT MAX(ReceiptNumber) + 1 FROM Avanti_inventoryReceipts ) , CR.ItemNumber , Convert(char(8), GETDATE(), 112) , PONum , 'FL-INV' , PH.POVendor ,
0 , 0 , 'O' , CR.QtyOrdered , QtyReceivedToday , QtyReceivedToday ,
Case #closePO
When 'N' Then Case When ( QtyOrdered - QtyReceivedToday ) < 0 Then 0 Else ( QtyOrdered - QtyReceivedToday) End
When 'Y' Then 0
Else 0 End
, PD.TransCost * QtyReceivedToday , IH.PriceWholeSale , IH.CostLast , QtyReceivedToday , 0 ,
'' , PODetailDescription , '' , '' , '' , Convert(char(8), GETDATE(), 112) ,
'' , '' , #employeeCode , '' , 'F L E X O' , '' ,
0 , 'Flexo Materials' , 0 , 0 , 0 , '' , 0
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH ON CR.PONum = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH ON CR.ItemNumber = IH.ItemNumber
IF ##ERROR <> 0
Begin
Select #nvErrMsg = 'Error entering into [InventoryReceipts] -' + [description]
From master..sysmessages
Where [error] = ##ERROR
RAISERROR ( #nvErrMsg , 16, 1 )
Goto Err_
End
Commit Transaction TransMain
Goto Exit_
Err_:
Rollback Transaction TransMain
Exit_:
SET XACT_ABORT OFF
You could do this:
insert into mytable (field1, field2, ...)
values (( SELECT MAX(field1) + 1 from mytable), 'value2', ...);
Why not looping? It should be quite efficient.
Since you already have a UNIQUE constraint on the field, you can:
Simply try to insert MAX(field1) + 1. Since there is index on UNIQUE field, MAX is fast.
If its passes, great you are done.
If it fails (which will typically be manifested as an exception in your client code), just try again until you succeed.
Most of the time, the INSERT will succeed right away. In rare instances where a concurrent user tries to insert the same value, you'll handle that gracefully by trying the "next" value.
I added an autonumber starting from 0 in client code and passed that in. Now I'm adding that value to the max receiptnumber to get a unique one. Also, I realized I already had an identity column in FI_CurrentReceiptData, but I didn't want to use that one because it won't start at 0 for each receipt set, and reseeding the identity each time seems like a waste of processor time.