SQL Table Variables to insert into a different table with additional values - sql

So I am using a cursor to loop through a bunch of records that my query returns. I have just updated some details in a table and now I want to pull the details from that table so I have used a temporary table.
So now I want to insert some values into a new table that are unrelated to the last and then the rest of the values would be a direct copy from the table variable...how can I do this?
I'll post below the section in question to help people see what I am trying to do.
The part in question is between the update status comment and the above not finished comment.
OPEN cur
FETCH NEXT FROM cur INTO #MembershipTermID , #EndDate , #MembershipID <VARIABLES>
WHILE ##FETCH_STATUS = 0
BEGIN
--PERFORM ACTION
DECLARE #TodaysDate DATETIME
SET #TodaysDate = getDate()
--CANCEL DETAIL
DECLARE #CancellationDetailID INT
INSERT INTO CancellationDetail(CancellationDetailID,RefundAmount,OldEndDate,EffectiveDate,CancelDate,ReasonCodeProgKey)
VALUES (0, 0.0, #EndDate, #TodaysDate, #TodaysDate, 'CANC_DORMANT')
SELECT #CancellationDetailID = SCOPE_IDENTITY()
INSERT INTO CancellationDetailAudit(StampUser,StampDateTime,StampAction,CancellationDetailID,RefundAmount,OldEndDate,EffectiveDate,CancelDate,ReasonCodeProgKey)
VALUES('SYSTEM', GetDate(), 'I', #CancellationDetailID, 0.0, #EndDate, #TodaysDate, #TodaysDate, 'CANC_DORMANT')
--LINK TO TERM
INSERT INTO MembershipTermCancellationDetail(CancellationDetailID,MembershipTermID)
VALUES(#CancellationDetailID, #MembershipTermID)
INSERT INTO MembershipTermCancellationDetailAudit(StampUser,StampDateTime,StampAction,MembershipTermCancellationDetailID,CancellationDetailID,MembershipTermID)
VALUES('SYSTEM', GetDate(), 'I', 0, #CancellationDetailID, #MembershipTermID)
--UPDATE STATUS
UPDATE MembershipTerm
SET MemberStatusProgKey = 'CANCELLED',
EndDate = #TodaysDate,
UpdateDateTime = #TodaysDate,
AgentID = 224,
NextTermPrePaid = 'False'
WHERE MembershipTermID = #MembershipTermID
DECLARE #MembershipTermTable TABLE
(
MembershipTermID int,
MemberStatusProgKey nvarchar (50),
StartDate datetime,
EndDate datetime,
AdditionalDiscount float,
EntryDateTime datetime,
UpdateDateTime datetime,
MembershipID int,
AgentID smallint,
PlanVersionID int,
ForceThroughReference nvarchar (255),
IsForceThrough bit,
NextTermPrePaid bit,
IsBillingMonthly bit,
LastPaymentDate datetime,
PaidToDate datetime,
IsIndeterminate bit
)
INSERT INTO #MembershipTermTable
SELECT MembershipTermID,
MemberStatusProgKey,
StartDate,
EndDate,
AdditionalDiscount,
EntryDateTime,
UpdateDateTime,
MembershipID,
AgentID,
PlanVersionID,
ForceThroughReference,
IsForceThrough,
NextTermPrePaid,
IsBillingMonthly,
LastPaymentDate,
PaidToDate,
IsIndeterminate
FROM MembershipTerm
WHERE MembershipTermID = #MembershipTermID
INSERT INTO MembershipTermAudit(StampUser,StampDateTime,StampAction,MembershipTermID,MemberStatusProgKey,StartDate,EndDate,AdditionalDiscount,EntryDateTime,UpdateDateTime,MembershipID,AgentID,PlanVersionID,ForceThroughReference,IsForceThrough,NextTermPrePaid,IsBillingMonthly,LastPaymentDate,PaidToDate,IsIndeterminate)
VALUES ('SYSTEM',#TodaysDate,'I',MembershipTermID,MemberStatusProgKey,StartDate,EndDate,AdditionalDiscount,EntryDateTime,UpdateDateTime,MembershipID,AgentID,PlanVersionID,ForceThroughReference,IsForceThrough,NextTermPrePaid,IsBillingMonthly,LastPaymentDate,PaidToDate,IsIndeterminate)
--ABOVE NOT FINISHED, NEED TO ADD AUDIT RECORD CORRECTLY
--Members
DECLARE #MembersTable TABLE
(
MembershipTermID int,
MemberStatusProgKey nvarchar (50),
StartDate datetime,
EndDate datetime,
AdditionalDiscount float,
EntryDateTime datetime,
UpdateDateTime datetime,
MembershipID int,
AgentID smallint,
PlanVersionID int,
ForceThroughReference nvarchar (255),
IsForceThrough bit,
NextTermPrePaid bit,
IsBillingMonthly bit,
LastPaymentDate datetime,
PaidToDate datetime,
IsIndeterminate bit
)
INSERT INTO #MembersTable
SELECT * FROM [MembershipTermPerson] WHERE MembershipTermID = #MembershipTermID
--Vehicles
FETCH NEXT FROM cur INTO #MembershipTermID , #EndDate , #MembershipID <VARIABLES>
END
CLOSE cur
DEALLOCATE cur

I think this would be a good case for a INSERT INTO SELECT statement
Something like
INSERT INTO MyTable (ColA, ColB, ColC)
SELECT
GETDATE(), A.MyCol, 'MyValue'
FROM MyOtherTable A
WHERE a.MyValue = 'What I Want'
Basically you skip the temp table, and just grab the value and inject everything at once.

Related

Insert values into table from another table

I have one table AttendanceLog.
Columns are:
EmpCode
Date
time
type
This is for attendance punch details
empcode date time type
01 19.08.2016 080530 64
01 19.08.2016 092030 64
01 19.08.2016 084030 65
The types are 64 for Intime, 65 for outtime.
I have another table.
Columns are
Empcode
Date
Intime
outtime
Now I want to insert into this table from attendancelog table.
Depending on the type I have to insert time into particular intime and outtime column.
pls help for an employee to fill firstIntime and lastouttime
My procedure:
CREATE PROCEDURE [dbo].[Attendance]
AS
BEGIN
SET NOCOUNT ON
Declare #Empcode varchar(50),
#Date varchar(50),
#time varchar(10),
#type varchar(10)
Declare attcursor Cursor
for
select AC.AttEmpCode,AttDate,AttTime,AttType
from BGUsersAttendanceCode AC inner join BGAttendanceTempTable AT
on AC.AttEmpCode=AT.AttEmpCode
order by AttType,AttDate
open attcursor
fetch next from attcursor into
#Empcode, #Date, #time, #type
WHILE ##FETCH_STATUS = 0
begin
insert into BGUsersAttendanceLog values(#Empcode,#Date,#time,#time)
fetch next from attcursor into
#Empcode, #Date, #time, #type
end
CLOSE attcursor
DEALLOCATE attcursor
END
GO
My interpretation of your requirements
You want to consolidate the rows in your attendance table, such that you end up with a single row for every (empcode, date) combination.
For every such row, you want the new InTime column to be populated with the earliest InTime value if more than one exists for that (empcode, date) combination.
Likewise, you want the new OutTime column to be populated with the latest OutTime values if more than one exists for that (empcode, date) combination.
A few additional notes
I notice that you use the varchar data type for all your columns. That's unfortunate. If possible, you really should use the appropriate types (datetime, int, etc.). But I'll ignore that here, and will assume that you are preserving the varchar values.
In your description, you say you have a single attendance source table. But your SP code suggests that your source data comes from a join between 2 tables. Since you haven't described this in detail, I'll just stick with your description of a single source table. You can adjust as necessary.
Setup
create table OldAttendanceLog (
AttEmpCode varchar(50),
AttDate varchar(50),
AttTime varchar(10),
AttType varchar(10)
)
insert into OldAttendanceLog
(AttEmpCode, AttDate, AttTime, AttType)
values
('01', '19.08.2016', '080530', '64'),
('01', '19.08.2016', '092030', '64'),
('01', '19.08.2016', '084030', '65'),
create table NewAttendanceLog (
AttEmpCode varchar(50),
AttDate varchar(50),
InTime varchar(10),
OutTime varchar(10)
)
INSERT statement
You don't need all that complicated cursor code. The insert can be accomplished in a single statement using conditional aggregation:
insert into NewAttendanceLog (AttEmpCode, AttDate, InTime, OutTime)
select AttEmpCode,
AttDate,
min(case when AttType = '64' then AttTime end),
max(case when AttType = '65' then AttTime end)
from OldAttendanceLog
group by AttEmpCode, AttDate

SQL Server: How to use result from one INSERT for another INSERT

I have a stored procedure that is meant to update two tables at once.
My problem here is that the first table has an auto-incrementing ID column ("commentID") and my second table has a relationship on this so I need the newly created ID from the first INSERT in order to make the second INSERT.
I tried the following which I can save without errors but it doesnt execute as it should and does not update the tables as intended.
Can someone tell me what I am doing wrong here ?
My SQL:
ALTER PROCEDURE [dbo].[MOC_UpdateComment]
#imgID int,
#commentID int = '999999',
#comment nvarchar(1000),
#lastUpdate nvarchar(50),
#modBy varchar(50)
AS
BEGIN
DECLARE #temp AS TABLE
(
commentID int
)
SET NOCOUNT ON;
BEGIN TRANSACTION;
INSERT INTO MOC_BlogComments
(
imgID,
comment
)
OUTPUT inserted.commentID INTO #temp(commentID)
SELECT #imgID,
#comment
INSERT INTO MOC_LogComments
(
commentID,
lastUpdate,
modTime,
modBy
)
SELECT commentID,
#lastUpdate,
GETDATE(),
#modBy
FROM #temp
COMMIT TRANSACTION;
END
DECLARE #imgID INT,
#commentID INT = '999999',
#comment NVARCHAR(1000),
#lastUpdate NVARCHAR(50),
#modBy VARCHAR(50)
DECLARE #MORC_BlogComments AS TABLE
(
id INT IDENTITY(1, 1) NOT NULL,
imgid INT,
comment VARCHAR(100)
)
DECLARE #MORC_LogComments AS TABLE
(
commentid INT,
lastupdate DATETIME,
modtime DATETIME,
modby VARCHAR(100)
)
DECLARE #TEMP AS TABLE
(
commentid INT
)
SET nocount ON;
BEGIN TRANSACTION;
INSERT INTO #MORC_BlogComments
(imgid,
comment)
output inserted.id
INTO #TEMP(commentid)
VALUES (#imgID,
#comment)
INSERT INTO #MORC_LogComments
(commentid,
lastupdate,
modtime,
modby)
SELECT commentid,
#lastUpdate,
Getdate(),
#modBy
FROM #temp
SELECT *
FROM #MORC_LogComments
Function SCOPE_IDENTITY() returns the identity of last insert operation. You can use it to get the value which you need to use in second INSERT statement
You can use it like this in your statement:
INSERT INTO MORC_BlogComments (imgID, comment)
VALUES (#imgID, #comment)
INSERT INTO MORC_LogComments (commentID, lastUpdate, modTime, modBy)
VALUES (SCOPE_IDENTITY(), #lastUpdate, GETDATE(), #modBy)

How to make a function that take user defined table type as parameter and return same in sql?

Actually I have created a User defined table type in sql server 2008. Structure is given below.
I am passing it as parameter in function and that function also return that type of table type. I am facing the problem, while I declare a variable of that type in function, inserting some data in it and return that parameter.
Table type structure is:
Create Type OfferWithSubscription as Table
(
OfferID int,
OfferUserID int,
OfferImage varchar(200),
OfferExactPrice Decimal(18,2),
OfferContent varchar(max),
OfferTitle varchar(100),
StartDate datetime,
EndDate datetime,
StartTime datetime,
StopTime datetime,
ShowToUser bit,
SubID int,
SubLevel varchar(100)
)
And the function, what I am trying to create is:
CREATE FUNCTION FN_ShowOffer
(
#Gold int,
#Silver int,
#Bronze int,
#table dbo.OfferWithSubscription Readonly )
RETURNS dbo.OfferWithSubscription
AS
BEGIN
DECLARE #ReturnTable AS dbo.OfferWithSubscription;
Declare #Case as varchar(20)
if(#Gold=0 and #Silver=1 and #Bronze=0 )
begin
set #Case='1S'
end
if(#Case='1S')
Begin
insert into #ReturnTable
select OfferID, OfferUserID, OfferImage,
OfferExactPrice, OfferContent,
OfferTitle, StartDate, EndDate,
StartTime, StopTime, ShowToUser,
SubID, SubLevel
from #table
where SubID=4
End
RETURN (
#ReturnTable
)
END
You'll just have to expand the type like below.
FYI - Can T-SQL function return user-defined table type?
CREATE FUNCTION FN_ShowOffer
(
#Gold int,
#Silver int,
#Bronze int,
#table dbo.OfferWithSubscription Readonly )
RETURNS #ReturnTable Table
(
OfferID int,
OfferUserID int,
OfferImage varchar(200),
OfferExactPrice Decimal(18,2),
OfferContent varchar(max),
OfferTitle varchar(100),
StartDate datetime,
EndDate datetime,
StartTime datetime,
StopTime datetime,
ShowToUser bit,
SubID int,
SubLevel varchar(100)
)
AS
BEGIN
Declare #Case as varchar(20)
if(#Gold=0 and #Silver=1 and #Bronze=0 )
begin
set #Case='1S'
end
if(#Case='1S')
Begin
insert into #ReturnTable
select OfferID,OfferUserID,OfferImage,OfferExactPrice,OfferContent,OfferTitle,
StartDate,EndDate,StartTime,StopTime,ShowToUser,SubID,SubLevel from #table where SubID=4
End
RETURN
END
And to further clarify, that's fully compatible and assignable to a variable of that table type, e.g. SQL Fiddle
declare #t OfferWithSubscription
insert #t
select * from fn_showoffer(1,2,3,#t)

Insert stored procedure passing parameter

I have this SQL statement
INSERT housingSurvey ([nameID], [houseID], [jobID], [Active], [comment], [needsMaintenance], [lastUpdateDate)
VALUES (#NAMEID, #HOUSEID, #JOBID, 1, #DUEDATE, #COMMENT, NULL, #LASTUPDATEDATE)
I tried this stored procedure, but I don't get the current date.
CREATE PROCEDURE housingSurveyS(
#NAMEID INT,
#HOUSEID INT,
#JOBID INT,
#COMMENT BIT,
#DUEDATE NVARCHAR,
CURRENTTIME)
AS
BEGIN
INSERT INTO housingSurvey(
[nameID],
[houseID],
[jobID],
[Active],
[comment],
[dueDate],
[needsMaintenance],
[lastupdatedate])
VALUES (
#NAMEID,
#HOUSEID,
#JOBID,
1,
#COMMENT,
#DUEDATE,
NULL,
#LASTUPDATEDATE)
END
Could you please take a look at what I did wrong. Thanks
UPDATE
I changed it CURRENTTIME to DATETIME as parameter to insert current date to [lastupdatedate]... it still doesn't work...
VALUES (
...
#DUEDATE,
#COMMENT
Are in the wrong order when related to the order of fields defined in the INSERTs statements field list, switch them around.
Edit
CREATE PROCEDURE housingSurveyS(
#NAMEID INT,
#HOUSEID INT,
#JOBID INT,
#COMMENT BIT,
#DUEDATE NVARCHAR(32) --add a size, should this be DATETIME
)
AS
BEGIN
INSERT INTO housingSurvey(
[nameID],
[houseID],
[jobID],
[Active],
[comment],
[dueDate],
[needsMaintenance],
[lastupdatedate]
) VALUES (
#NAMEID,
#HOUSEID,
#JOBID,
1,
#COMMENT,
#DUEDATE,
NULL,
GETDATE()
)
END

SQL Server 2008: Help in optimizing a query using a cursor

I need to rewrite this so it does not cause an overrun on my db. I need to rewrite it so it does not use a cursor.
Thank you.
UPDATED Here's some test data:
CREATE TABLE #TableB(SKU INT, BeginYear INT, EndYear INT, OptionA VARCHAR(10), OptionB VARCHAR(10))
INSERT INTO #TableB(SKU, BeginYear, EndYear, OptionA, OptionB)
VALUES (1, 1920, 1950, 'option1', 'option1'),
(1, 1980, 2001, 'option1', 'option2'),
(1, 1940, 1952, 'option1', 'option1'), --overlapping years
(2, 2001, 2005, 'option1', 'option1')
CREATE TABLE #TableA(SKU INT, OptionA VARCHAR(10), OptionB VARCHAR(10), Years INT)
Then you can try a recursive CTE:
;WITH CTE AS
(
SELECT DISTINCT SKU, BeginYear, EndYear, OptionA, OptionB
FROM #TableB
UNION ALL
SELECT SKU, BeginYear+1, EndYear, OptionA, OptionB
FROM CTE
WHERE BeginYear < EndYear
)
INSERT INTO #TableA(SKU, OptionA, OptionB, Years)
SELECT DISTINCT SKU, OptionA, OptionB, BeginYear
FROM CTE
OPTION(MAXRECURSION 0)
SELECT *
FROM #TableA
ORDER BY SKU, OptionA, OptionB, Years
Here there's no cartesian product.
You can easily substitute a while loop for a cursor and if you are blowing out your tempdb then do some intermediate transactions
declare #counter int
declare #temptable as tatble (RecID int Identity(1,1),
SKU Varchar(25),
OptionA Varchar(50),
OptionB Varchar(50),
CurrentYear Int,
EndYear Int)
insert into #temptable
Select SKU,OptionA, OptionB, BeginYear,EndYear
From TableB
set #counter = (select max(recid) from #temptable)
begin transaction
while #counter <> 0
Begin
(***whatever sql logic***)
if (#counter % 5000 = 0) and ##error = 0
commit Transaction
begin Transaction
set #counter = #counter -1
End
commit transaction
May be use less number of times the insert happen
Declare #temp table (
SKU Varchar(25),
OptionA Varchar(50),
OptionB Varchar(50),
[Year] Int
)
While ##FETCH_STATUS = 0
Begin
While #CurrentYear <= #EndYear
Begin
Insert Into #temp(SKU, OptionA, OptionB, Years)
Values(#SKU, #OptionA, #OptionB, #CurrentYear)
Set #CurrentYear = #CurrentYear + 1
End
Insert Into TableA
Select * From #temp
Delete From #temp
Fetch Next From #Row Into #SKU, #CurrentYear, #EndYear, #OptionA, #OptionB
End