I am trying to acheive like this at the end of the procedure i need all the rows in
one temp table
How can I accomplish this
if #i > 1
begin
select * from into #tempTbl1 from payments
where method = 'test1'
end
else
begin
select * from into #tempTbl2 from payments
where method = 'test1'
end
insert into #tempTbl1 select * from #tempTbl2
select * from #tempTbl1
despite the previous logic issue, to simplely get all rows from both temp tables , use UNION:
select * from #tempTbl1
UNION ALL
SELECT * from #tempTbl2
The problem you have here is that based on your IF/ELSE you will never had both tables. Your final INSERT INTO requires that both tables exist. You may need to create the objects before hand in the stored proc before you try to populate, then insert into the tables.
This also begs the question, if you're going to later insert everything in #tempTbl1 anyways, which is created in the SELECT INTO statement, why have the #tempTbl2 in the first place?
create procedure dbo.testing
(#i int)
AS
if #i > 1
begin
print 'In condition 1'
select *
into #tempTbl1
from payments
where method = 'test1'
end
else
begin
print 'In condition 2'
select *
into #tempTbl2
from payments
where method = 'test1'
end
print 'Made it out of the if else'
insert into #tempTbl1
select *
from #tempTbl2
-- Never gets this far...
print 'In the final select'
select *
from #tempTbl1
If you're committed to this method, then you may need to check to see if the table exists:
IF EXISTS (SELECT * FROM tempdb.sys.objects WHERE object_id = OBJECT_ID(N'tempdb.dbo.#tempTbl1') AND type in (N'U'))
print 'Table is there'
Update based on comments
Based on your comments, this will work. The SELECT...INTO statement you originally posted lets you create a table based on the data types of the columns your selecting from, but the destination table can't already exist. If you define the structure you're going to insert into beforehand, you can have the two conditions evaluate and end up with a single table as the result.
(Note - my "payments" table only had two columns, "method" and "col2". You would want to specify the columns you need in the CREATE TABLE and the SELECT)
create procedure dbo.testing
(#i int)
AS
create table #tempTbl1
(method varchar(10)
, col2 int)
if #i > 1
begin
insert into dbo.#tempTbl1
select method, col2
from payments
where method = 'test1'
end
else
begin
insert into dbo.#tempTbl1
select method, col2
from payments
where method = 'test1'
end
select *
from #tempTbl1
Related
Trying to learn triggers and can't seem to wrap my head around whether this is the best way to go about this. There is a total of 'tickets' that I would like to count and put into a column for an 'order'.
CREATE TRIGGER DAILYTICKETTOTALS
ON db.ORDER
AFTER UPDATE
AS
BEGIN
INSERT INTO db.ORDER (
--Finding the order they made for the day:
SELECT * FROM db.ORDER
WHERE DESCRIPTION = 'specific description' AND
CAST(CAST(CAST(GETDATE()AS float) AS int) AS datetime) =
CAST(CAST(CAST(db.ORDER.STARTDATE AS float) AS int) AS datetime)
AND db.ORDER.CREATEDBY = 'Last, First'
)
SET db.ORDER.COLUMNTOTALS VALUES(
--Finding the total of tickets input for the day
SELECT COUNT(*)
FROM db.ticket
WHERE CAST(CAST(CAST(db.ticket.DATE AS float) AS int) AS datetime) =
CAST(CAST(CAST(GETDATE()AS float) AS int) AS datetime)
AND db.ticket.INPUTBY = 'Last, First');
Thanks for any help, and I appreciate you reviewing this.
Do some research on the "Special" tables available inside a trigger, such as "INSERTED" as that will give you the details of the rows that have been updated, and you can join that to anything else (including the actual table being updated) that you need to. Remember that you should not assume there is only 1 row updated, as the trigger will fire once per batch, not once per row.
This is a version of your stored proc that assumes that each order has a unique ID named OrderID, and that both the ticket and order table have a personID rather than looking for them by name. If not, they should, and if you cant change it then use your existing messy joins.
CREATE TRIGGER DAILYTICKETTOTALS
ON db.ORDER
AFTER UPDATE
AS
BEGIN
update o
set columntotals=TicketNum
from inserted
join db.[order] o on o.orderid=inserted.orderid
join (
select convert(date,ticket,[date]) as ticketdate, PersonID, count(*) as TicketNum
from db.ticket
group by convert(date,ticket,[date]) as ticketdate, PersonID
) t on t.PersonID=o.PersonID and t.ticketdate=convert(date,getdate())
This solved my problem, in case any of you were curious. I don't know if its ideal, but it works.
CREATE TRIGGER DAILYTICKETTOTALS
ON db.ORDER
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE #INS NVARCHAR(50)
SELECT #INS = NAMECOLUMN FROM INSERTED
WHERE DESCRIPTION = 'specific description' AND
CAST(CAST(CAST(STARTDATE AS float) AS int) AS datetime)=
CAST(CAST(CAST(GETDATE() AS float) AS int) AS datetime)
END
IF #INS = ‘Last, First’
BEGIN
UPDATE db.ORDER
SET COLUMNTOTALS = EXAMPLENAME.CT
FROM (SELECT COUNT(*) AS CT FROM ticket WHERE INPUTBY = ‘Last, First’) EXAMPLENAME
WHERE DESCRIPTION = 'specific description' AND INPUTBY = ‘Last, First’
END
BEGIN
Not sure what I'm missing. When I debug and step through the INSERT query I've included below, I see that '%a%' is the value of #Answer, and 103 is the value for #ItemId.
IF EXISTS is always evaluating to false when I insert the values shown beneath:
CREATE TRIGGER TR_cc_Additional_Information_Answers_INS
ON cc_Additional_Information_Answers
AFTER INSERT
AS
BEGIN
CREATE TABLE temp_answers
(
TempAnswer VARCHAR(50),
TempAdditional_Information_ItemID INT
)
INSERT INTO temp_answers (TempAnswer, TempAdditional_Information_ItemID)
SELECT Description, Additional_Information_ItemID
FROM inserted
DECLARE #Answer varchar(50)
SELECT #Answer = '''%' + t.TempAnswer + '%''' FROM temp_answers t
DECLARE #ItemId int
SELECT #ItemId = t.TempAdditional_Information_ItemID FROM temp_answers t
IF EXISTS(SELECT 1
FROM cc_Additional_Information_Answers a
WHERE a.Description LIKE #Answer
AND a.Additional_Information_ItemID = #ItemId)
BEGIN
RAISERROR('Answer is too similar to pre-existing answers for this item', 16, 1)
ROLLBACK TRANSACTION
RETURN
END
DROP TABLE temp_answers
END
GO
And this is my insert query:
INSERT INTO cc_Additional_Information_Answers (Additional_Information_ItemID, Description)
VALUES (103, 'a')
And the pre-existing record:
Thanks in advance, SQL community!
EDIT: this also does not behave as expected. . .
INSERT INTO cc_Additional_Information_Answers (Additional_Information_ItemID, Description)
VALUES (103, 'a')
Given this data
Your IF EXISTS will always evaluate to true because the inserted value is already inserted (although it can be rolled back) when the trigger runs (it's an "AFTER" trigger).
So you will want to inspect only those records that existed in the table before the insertion. I always use an outer join for this. Also: I would never create a table in a trigger. The following should work as expected:
CREATE TRIGGER TR_cc_Additional_Information_Answers_INS ON cc_Additional_Information_Answers
AFTER INSERT
AS
BEGIN
IF EXISTS(
SELECT 1 FROM cc_Additional_Information_Answers a
LEFT OUTER JOIN inserted i ON a.Additional_Information_AnswerID = i.Additional_Information_AnswerID
INNER JOIN inserted temp ON a.Additional_Information_ItemID = temp.Additional_Information_ItemID
WHERE a.Description LIKE '%' + temp.Description + '%'
AND i.Additional_Information_AnswerID IS NULL
)
BEGIN
RAISERROR('Answer is too similar to pre-existing answers for this item', 16, 1)
ROLLBACK TRANSACTION
RETURN
END
END
GO
In procedure, I need to make two or more queries resulting the same columns and unite that resulting rows in one returning table. Example
CREATE PROC tmpProc
AS
BEGIN
-- Making first query
SELECT * INTO #resultTable FROM tableOne;
-- Making second query, resulting columns are totally the same
SELECT * INTO #resultTable FROM tableTwo;
-- Return rowset from temporary table
SELECT * From #resultTable;
END
But this type of proc failed, because There is already an object named #resultTable in the database
Here are two sample to do that:
IF OBJECT_ID('tempdb..#resultTable') IS NOT NULL DROP TABLE #resultTable
------ 1 use insert into select---------------------
SELECT * INTO #resultTable FROM tableOne;
INSERT INTO #resultTable SELECT * FROM tableTwo
------ 1 use union ---------------------
SELECT * INTO #resultTable FROM (
SELECT * FROM tableOne
UNION ALL
SELECT * FROM tableTwo
) AS t
This will work if columns are same in two tables.
CREATE PROC tmpProc
AS
BEGIN
-- Making first query
SELECT * FROM tableOne;
UNION ALL
SELECT * FROM tableTwo;
END
CREATE PROC tmpProc
AS
BEGIN
-- Making first query
SELECT * INTO #resultTable FROM tableOne;
-- Making second query, resulting columns are totally the same
INSERT INTO #resultTable SELECT * FROM tableTwo;
-- Return rowset from temporary table
SELECT * From #resultTable;
END
Try this
CREATE PROC tmpProc
AS
BEGIN
select * into #resultTable from (
SELECT col1,col2,col3...coln FROM tableOne;
union all
SELECT col1,col2,col3...coln FROM tableTwo;
) as a
SELECT * From #resultTable;
END
I have an SSIS package which will first run my sp_doSomething. This stored procedure will select data from several different tables and join them for possible storage into dbo.someTable. But I only want that IF the select is > 1 row of selected data.
I want to then have a precedence restraint that looks at the amount of rows my stored procedure returned.
If my row count > 1, then I want to take the results of the stored procedure and insert them into one of my tables.
Otherwise, I will record an error/send an email, or whatever.
I really don't want to run this stored procedure more then once, but that is the only way I could think to do it (Run it, count the rows. Then, run it again and insert the result).
I'm a complete TSQL/SSIS newb. So I'm sorry if this question is trivial.
I can't find a good answer anywhere.
Create a variable with Package Scope of type Int32 and name rowcount.
Data Flow
Control Flow
you can try this
declare #tableVar table(col1 varchar(100))
declare #Counter int
insert into #tableVar(col1) exec CompanyNames
set #Counter = (select count(*) from #tableVar)
insert into Anytable(col) Values (#counter)
Within the Stored Proc, write the results to a #Temp. Then Select Count(*) from the #Temp, into a variable.
Select #intRows = Count(*) from myTempResults
Then evaluate the value of #intRows.
If #intRows > 1 BEGIN
Insert Into dbo.SomeTable
Select * from #Temp
End
Will a #temp table work for you?
IF OBJECT_ID('tempdb..#Holder') IS NOT NULL
begin
drop table #Holder
end
CREATE TABLE #Holder
(ID INT )
declare #MyRowCount int
declare #MyTotalCount int = 0
/* simulate your insert, you would read from your real table(s) here */
INSERT INTO #HOLDER (ID)
select 1 union all select 2 union all select 3 union all select 4
Select #MyRowCount = ##ROWCOUNT, #MyTotalCount = #MyTotalCount + #MyRowCount
Select 'TheMagicValue1' = #MyRowCount, 'TheMagicTotal' = #MyTotalCount
INSERT INTO #HOLDER (ID)
select 5 union all select 6 union all select 7 union all select 8
/* you will note that I am NOT doing a count(*) here... which is another strain on the procedure */
Select #MyRowCount = ##ROWCOUNT, #MyTotalCount = #MyTotalCount + #MyRowCount
Select 'TheMagicValue1' = #MyRowCount, 'TheMagicTotal' = #MyTotalCount
/* Optional index if needed */
CREATE INDEX IDX_TempHolder_ID ON #Holder (ID)
/* CREATE CLUSTERED INDEX IDX_TempHolder_ID ON #Holder (ID) */
if #MyTotalCount > 0
BEGIN
Select 'Put your INSERT statement here'
END
/* this will return the data to the report */
Select ID from #HOLDER
IF OBJECT_ID('tempdb..#Holder') IS NOT NULL
begin
drop table #Holder
end
Following is what my logic is supposed to do
IF #id = 1
BEGIN
SELECT * INTO #abc from table1
END
IF #id = 2
BEGIN
SELECT * INTO #abc frm table2
END
However, when I execute my statements I get the error saying
there is already an object named #abc..
Any suggestions to overcome this error please?
You can't. The parser doesn't understand your IF logic and it treats both SELECT INTO statements as things that will happen.
What you should do is:
IF #id = 1
BEGIN
SELECT * INTO #abc1 from table1
END
IF #id = 2
BEGIN
SELECT * INTO #abc2 frm table2
END
IF #id = 1
SELECT * FROM #abc1;
ELSE
SELECT * FROM #abc2;
After all, you need to know the different columns that are in the #temp table in order to do anything meaningful with it, right?
(Or avoid temp tables altogether.)
Another possible solution:
CREATE TABLE #abc (
--put schema here
)
IF #id = 1
BEGIN
insert into #abc
select * from table1
END
IF #id = 2
BEGIN
insert into #abc
select * from table2
END
select * from #abc
drop table #abc;
You should always use the column names instead of * because it's better in terms of performance.
And also, select * finds all the columns currently in a table, changes in the structure of a table such as adding, removing, or renaming columns automatically modify the results of select *. Listing columns individually gives you more precise control over the results.