Usage of Array in Sql Possible? - sql

I am trying to write a stored proicedure that gets all the townID's from Region_TownPage table. Then i should get the City, Stateinitials of all the townID's.
Alter PROCEDURE [dbo].[GetTownDetailsforRegionID]
#RegionID int
AS
BEGIN
Declare #townID int
set #townID = (Select townID from Region_TownPage where regionID =#RegionID)
SET NOCOUNT ON;
Select City, StateInitials,TownID from TownPage where TownID =#townID
END
I do not know how to use an array here in sql. If someone could help me doing this, i really appreciate that.
Thanks in advance!!

I don't think you need an array - you just need to join the tables?
Select r.RegionId,
t.TownId,
t.City,
t.StateInitials
From Region_TownPage r
Join TownPage t on r.TownId = t.TownId
Where r.RegionId = #RegionId

you would declare a table variable instead of an int. so it would be something like
DECLARE #tab table(townID int)
INSERT INTO #tab
SELECT townID from Region_TownPage WHERE regionID = #RegionID
Select * From TownPage WHERE TownID IN(SELECT townID FROM #tab)

Related

How to add an update statement value to a variable?

I want to save data in a variable and use it later in a procedure.
UPDATE acc_Account
SET acc_Account.CompanyID = ( SELECT TOP 1
utl_Company.CompanyID
FROM utl_Company
ORDER BY CompanyID DESC
)
WHERE acc_Account.AccountNumber = #AccountNumber
how can I save the CompanyID in a variable to use it in an insert statement later on?
Have this in the beginning of your code:
declare #var varchar(20) -- change the data type according to your needs
set #var = (SELECT TOP 1 utl_Company.CompanyID FROM utl_Company ORDER BY CompanyID DESC)
Create a select local variable before the update statement, then set it, then use it.
DECLARE #companyID INT;
SELECT #companyID = "YOUR QUERY";
I think the efficient way would be using OUTPUT clause
DECLARE #TAB TABLE (CompanyID BIGINT )
UPDATE acc_Account
SET acc_Account.CompanyID = (
SELECT max(CompanyID) FROM utl_Company
)
output inserted.CompanyID into #TAB
WHERE acc_Account.AccountNumber = #AccountNumber
SELECT * FROM #TAB

Can we create a view after a script from a variable?

I would like to create a view at the end of the following request.
I know that 'create view' must be the first statement in a query batch. My problem is that for this query i must use a variable (#listOfIDRUB).
This variable is only fill correctly at the end of my little script.
I also have tried to create the view before my first declaration but it created a problem with "DECLARE".
So is it possible to create a view easily from the result of my script or i have to do something else ?
DECLARE #CounterResId int;
DECLARE #lePath varchar(255);
DECLARE #listOfIDRUB TABLE (EXTERNALREFERENCE uniqueidentifier, ID varchar(255), DOCID varchar(255) );
DECLARE #Max int;
SET #lePath = '';
SET #CounterResId = 1;
SET #Max = (SELECT COUNT(*) FROM SYNTHETIC..EXTRANET_PURGE WHERE TYPE_SUPPR = 'ResId')
WHILE (#CounterResId <= #Max )
BEGIN;
set #lePath =
(select tmp.lePath from
(
select row_number() over(order by path)as NumLigne, CONCAT(path, '%' ) as lePath from RUBRIQUE
WHERE MODELE = 'CAEEE64D-2B00-44EF-AA11-6B72ABD9FE38'
and CODE in (SELECT ID FROM SYNTHETIC..EXTRANET_PURGE where TYPE_SUPPR='ResId')
) tmp
WHERE tmp.NumLigne = #CounterResId)
INSERT INTO #listOfIDRUB(EXTERNALREFERENCE, ID, DOCID)
SELECT SEC.EXTERNALREFERENCE , SEC.ID, SEC.DOCUMENTID
FROM WEBACCESS_FRONT..SECTIONS sec
inner join rubrique rub ON rub.ID_RUBRIQUE = sec.EXTERNALREFERENCE
inner join template_tree_item tti ON tti.id_template_tree_item = rub.modele
inner join template t ON t.id_template = tti.template
WHERE t.CODE IN (SELECT TEMPLATE_CODE from SYNTHETIC..EasyFlowEngineListTemplateCode)
and rub.path like #lePath
print #CounterResId;
print #lePath;
set #CounterResId = #CounterResId + 1;
END;
select * from #listOfIDRUB;
Instead of select * from #listOfIDRUB
i wanted create view test as select * from listOfIDRUB
I have also tried create view test as (all my request)
Whenever you ask something about SQL please state your RDBMS (product and version). The answers are highly depending on this...
From your code I assume this is SQL Server.
So to your question: No, a VIEW must be "inlineable" (single-statement or "ad-hoc") statement.
You might think about a multi-statement UDF, but this is in almost all cases a bad thing (bad performance). Only go this way, if your result table will consist of rather few rows!
Without knowing your tables this is rather blind walking, but you might try this (add parameters, if you can transfer external operations (e.g. filtering) into the function):
CREATE FUNCTION dbo.MyFunction()
RETURNS #listOfIDRUB TABLE (EXTERNALREFERENCE uniqueidentifier, ID varchar(255), DOCID varchar(255) )
AS
BEGIN
DECLARE #CounterResId int;
DECLARE #lePath varchar(255);
DECLARE #Max int;
SET #lePath = '';
SET #CounterResId = 1;
SET #Max = (SELECT COUNT(*) FROM SYNTHETIC..EXTRANET_PURGE WHERE TYPE_SUPPR = 'ResId')
WHILE (#CounterResId <= #Max )
BEGIN;
set #lePath =
(select tmp.lePath from
(
select row_number() over(order by path)as NumLigne, CONCAT(path, '%' ) as lePath from RUBRIQUE
WHERE MODELE = 'CAEEE64D-2B00-44EF-AA11-6B72ABD9FE38'
and CODE in (SELECT ID FROM SYNTHETIC..EXTRANET_PURGE where TYPE_SUPPR='ResId')
) tmp
WHERE tmp.NumLigne = #CounterResId)
INSERT INTO #listOfIDRUB(EXTERNALREFERENCE, ID, DOCID)
SELECT SEC.EXTERNALREFERENCE , SEC.ID, SEC.DOCUMENTID
FROM WEBACCESS_FRONT..SECTIONS sec
inner join rubrique rub ON rub.ID_RUBRIQUE = sec.EXTERNALREFERENCE
inner join template_tree_item tti ON tti.id_template_tree_item = rub.modele
inner join template t ON t.id_template = tti.template
WHERE t.CODE IN (SELECT TEMPLATE_CODE from SYNTHETIC..EasyFlowEngineListTemplateCode)
and rub.path like #lePath
--print #CounterResId;
--print #lePath;
set #CounterResId = #CounterResId + 1;
END;
RETURN;
END
You can call it like this (very similar to a VIEW)
SELECT * FROM dbo.MyFunction();
And you might even use it in joins...
And last but not least I'm quite sure, that one could solve this without declares and a loop too...

Iterate through values of a table variable in a stored procedure

I am writing a stored proc as follows:
CREATE PROCEDURE ListByOrderRequestId
#EntityId int,
#EntityTypeId varchar(8)
AS
BEGIN
SET NOCOUNT ON;
Declare #IDS table(OrderRequestId int)
INSERT INTO #IDS
SELECT OrderRequestTaskId
FROM OrderRequestTask ORT WITH (NOLOCK)
WHERE ORT.OrderRequestId = #EntityId
SELECT N.EntityNoteId AS Id,
N.UpdateDate AS DateStamp,
N.EntityNoteText,
N.EntityId,
N.EntityNoteTypeId,
N.EntityTypeId
FROM EntityNote N
WHERE (N.EntityId = #EntityId AND N.EntityTypeId ='ORDREQ')
*OR(N.EntityId = #IDS VAL1 AND N.EntityTypeId ='TASK')
OR(N.EntityId = #IDS VAL2 AND N.EntityTypeId ='TASK')*
END
The table #IDS can have 0 or 1 or more values in it. I want to loop through the values in #TDS and create the where clause above accordingly. Please help me.
As opposed to looping through the table, you could just use it in your where clause like this:
Select * From {Your Table} Where ID in (Select OrderRequestId From IDS)
This is much faster than looping.

Dynamic sql using table variable -TSQL

My problem is using a table variable in a exec.
declare #sort_col nvarchar(1000) = 'itm_id'
declare #sort_dir nvarchar(4) = 'desc'
declare #filters nvarchar(1000) = ' and itm_name like ''%aa%'''
declare #temp table
(
itm_id int
)
insert into #temp
EXEC('select itm_id from Tblitm where itm_name not like ''%aa%''')
EXEC('select * from (select (ROW_NUMBER() OVER (ORDER BY '+#sort_col+' '+#sort_dir+')) row_num, * FROM (select itm_id, itm_name,
dbo.fnItmsHistory(itm_id) itm_history
from dbo.Tblitm as itm
left outer join '+#temp+' as temp on itm.itm_id = temp.itm_id
where itm_id=itm_id and temp.itm_id = null '+#filters+') as x) as tmp')
It says Must declare the scalar variable "#temp" when the temp table is declared i tried using original temp table and it worked, but i had problems when trying to update my entity model.So is there any solution for this problem?
Note:
I must use exec because in filters i store string for the where clause.
Try moving the table variable inside the dynamic statement.
EXEC('
declare #temp table
(
itm_id int
)
insert into #temp
select itm_id from Tblitm where itm_name not like ''%aa%''
select * from (select (ROW_NUMBER() OVER (ORDER BY '+#sort_col+' '+#sort_dir+')) row_num, * FROM (select itm_id, itm_name,
dbo.fnItmsHistory(itm_id) itm_history
from dbo.Tblitm as itm
left outer join #temp as temp on itm.itm_id = temp.itm_id
where itm_id=itm_id and temp.itm_id = null '+#filters+') as x) as tmp')
For solution i had to use a temp table and then on the start of my stored procedure i used the if condition from the EF can't infer return schema from Stored Procedure selecting from a #temp table anwser.
It's the best solution for this scenario i think.

Must declare the scalar variable #tempTbl

I get this error even though i have tried what other post suggested still the same error
but when i run select it works OK...
any help would be greatly appreciated
ALTER PROCEDURE UpdateCustomers
#XML AS XML
AS
DECLARE #tempTbl TABLE(
tblID INT ,
Customer_name NVARCHAR(30),
Customer_Code NVARCHAR(10)
)
INSERT INTO #tempTbl(tblID, Customer_name, Customer_Code)
SELECT
Item.element.value('#tblID', 'int'),
Item.element.value('#Customer_name', 'nvarchar(30)'),
Item.element.value('#Customer_Code', 'nvarchar(10)')
FROM
#xml.nodes('/root/item') AS Item(element)
--SELECT * FROM #tempTbl---it runs ok
UPDATE dbo.Customers
SET
dbo.Customers.Customer_name = #tempTbl.Customer_name,
dbo.Customers.Customer_Code = #tempTbl.Customer_Code
from dbo.Customers
inner join #tempTbl
on Customers.tblID =#tempTbl.tblID
Try aliasing the table variable in the UPDATE
e.g.
UPDATE dbo.Customers
SET
dbo.Customers.Customer_name = tmp.Customer_name,
dbo.Customers.Customer_Code = tmp.Customer_Code
from dbo.Customers
inner join #tempTbl tmp
on Customers.tblID = tmp.tblID