Codeigniter with Temp Table SQL - sql

I'm trying to create a query with a Stored Procedure. I'm able to create it and there is no problem when i running it. Here is My StoredProcedure
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE SP_Penilaian
#Nip varchar(50)
AS
BEGIN
select * INTO #tMP from historyposition where nip = ''+#Nip+'' order by approveddate desc
declare #NewPosition varchar(50), #NewPositionLast varchar(50), #ApproveDate datetime, #ApproveDateLast datetime
select top 1 #NewPositionLast = NewPosition, #ApproveDateLast=ApprovedDate from #tmp
WHILE EXISTS (SELECT * FROM #tMP)
BEGIN
select top 1 #NewPosition = NewPosition, #ApproveDate=ApprovedDate from #tmp
if (#NewPosition = #NewPositionLast)
begin
set #NewPositionLast = #NewPosition
set #ApproveDateLast = #ApproveDate
end
else
begin
break
end
delete top(1) #tMP
END
select #NewPositionLast 'LatesUpgradePosition' , #ApproveDateLast 'LatesUpgradeDate'
END
GO
this how i run it
sp_penilaian '1500060'
And here is the resullt
Ok. The problem is when i'm trying to call my SP in Codeigniter.
$nip = '1500060';
$filt_outlet = $this->db->query("SP_Penilaian '".$nip."'")->row();
and then i'm trying to check my data with this
echo "<pre>".print_r($filt_outlet)."</pre>";
But i get empty data. So how to use temp table with CodeIgniter? or if i can't use temp table can i just create table and drop it in my Stored Procedure?
Sorry for my bad english.

Try Add SET NOCOUNT ON; after BEGIN
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE SP_Penilaian
#Nip varchar(50)
AS
BEGIN
SET NOCOUNT ON; /*<--Add here*/
select * INTO #tMP from historyposition where nip = ''+#Nip+'' order by approveddate desc
declare #NewPosition varchar(50), #NewPositionLast varchar(50), #ApproveDate datetime, #ApproveDateLast datetime
select top 1 #NewPositionLast = NewPosition, #ApproveDateLast=ApprovedDate from #tmp
WHILE EXISTS (SELECT * FROM #tMP)
BEGIN
select top 1 #NewPosition = NewPosition, #ApproveDate=ApprovedDate from #tmp
if (#NewPosition = #NewPositionLast)
begin
set #NewPositionLast = #NewPosition
set #ApproveDateLast = #ApproveDate
end
else
begin
break
end
delete top(1) #tMP
END
select #NewPositionLast 'LatesUpgradePosition' , #ApproveDateLast 'LatesUpgradeDate'
END
GO

It doesn't look like the problem lies with the actual stored procedure but with the way you ar calling it. Try:
$nip = '1500060';
$sp = "CALL SP_Penilaian(?)";
And to pass the nip to the stored procedure you can use CodeIgniter's database query funtion like so:
$filt_outlet = $this->db->query($sp, array('nip'=>$nip));

Related

While loop became slower after some recursions in sql server

I have a stored procedure which uses a while loop to iterate to each record
and do some calculations. The stored procedure has the following logic:
Inserts some records from old_table to new_table for a specific range
(7.8 million records) . insert took 4 minutes.
Then it copies records which have amount > 100 into a temp table
(37 000 records).
create clustered index on the id column of temp table.
start the while loop to iterate to each id column in temp table (total 37 000 records).
for each iteration a stored procedure is called inside the while loop.
The Sp works fine (faster) Up to 5 000 records (it completes in 5 mins)
but after 5 000 there is a delay in processing records. The delay occurs after processing each 100 records. Is there any reason for this delay?
sample structure of the stored procedure:
use my_db
go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID('[dbo].[usp_datacopy]') IS NULL -- Check if SP Exists
EXEC('CREATE PROCEDURE [dbo].[usp_datacopy] AS SET NOCOUNT ON;') -- Create dummy/empty SP
GO
ALTER PROCEDURE [dbo].[usp_datacopy]
#Startdate datetime,
#Enddate datetime,
#Percent int
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN
DECLARE #PerVal NUMERIC(10,2) = #percent /100.00,--Get the percent value for input.
#wkstartdate DateTime,
#wkenddate Datetime,
#OfficeID int,
#id int = 1,
#spcount int ,
#rdate datetime,
IF OBJECT_ID ('TEMPDB..#temptable') IS NOT NULL
DROP TABLE #temptable
INSERT INTO [dbo].[new_table]
( TimeID, OfficeID, dateval, rHour, Complexity,RowCountval)
SELECT TimeID + 364, OfficeID,dateadd(dd,364,dateval),rHour, Complexity , RowCountval,
FROM [dbo].[old_table] WITH (NOLOCK)
WHERE dateval BETWEEN #Startdate AND #Enddate
--select Day records with value > 100
SELECT ROW_NUMBER() over(order by timeid) id,TimeID, OfficeID, dateval, rHour, Complexity,RowCountval
INTO #temptable
FROM [dbo].[new_table] WITH (NOLOCK)
WHERE RDATE BETWEEN #wkstartdate AND #wkenddate
AND RowCountval > 100
CREATE CLUSTERED INDEX id_index on #temptable (id)
SELECT #spcount = COUNT (1) from #temptable
WHILE #id <= #spcount --37000 records
BEGIN
SELECT #OfficeID = officeid FROM #temptable WHERE id = #id
SELECT #rdate = dateval FROM #temptable WHERE id = #id
EXEC CalcPercentforEachRecord #rdate, #OfficeID, #PerVal
PRINT #ID
SELECT #id = #id + 1
SELECT #OfficeID = NULL
SELECT #rdate = NULL
END
IF ##ERROR = 0
BEGIN
COMMIT TRAN;
END
END TRY
BEGIN CATCH
SELECT ##ERROR AS ERROR,ERROR_MESSAGE() AS ErrorMessage,ERROR_LINE() AS ErrorLineNo
ROLLBACK TRAN;
END CATCH
SET NOCOUNT OFF;
END

Azure SQL Database trigger is not running and I cannot seem to figure out why

I'm trying to update the status column of a table when the table has been edited. I use a similar trigger on another table to update this status but when I try to put the trigger on the table itself it will not run.
ALTER TRIGGER dbo.tr_Invoice_SetInvoiceStatus_Update
ON dbo.Invoice
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #InvoiceID int
DECLARE #TotalInvoice DECIMAL(18,2)
DECLARE #TotalPayments DECIMAL(18,2)
DECLARE #InvoiceStatus NVARCHAR(50)
DECLARE #InvoiceStatusID INT
SELECT #InvoiceID = ID
FROM Inserted i
SELECT #TotalPayments = IsNull(Sum(ph.Amount), 0)
FROM PaymentHistory ph
WHERE InvoiceID = #InvoiceID
SELECT #TotalInvoice = ISNULL(Total, 0)
FROM Invoice
WHERE ID = #InvoiceID
IF (#TotalPayments > 0)
BEGIN
IF (#TotalPayments >= #TotalInvoice)
BEGIN
SELECT #InvoiceStatus = 'Paid'
END
ELSE
BEGIN
SELECT #InvoiceStatus = 'Partially Paid'
END
END
ELSE
BEGIN
SELECT #InvoiceStatus = 'Open'
END
SELECT #InvoiceStatusID = ID
FROM dbo.InvoiceStatus
WHERE [Name] = #InvoiceStatus
UPDATE dbo.Invoice
SET InvoiceStatusID = #InvoiceStatusID
WHERE ID = #InvoiceID
END
GO
Any help would be great?

execute stored procedure with a loop and combine results

I have a stored procedure in SQL server 2008.
This stored procedure (lets call it sp1), accepts ID (string),FromDate,ToDate and returns col1,col2,col3
I tried to alter sp1 to accept IDList (ID1,ID2,...,IDn), but it is way over my head.
I need help with creating a new SP (lets call it SP2) that accepts IDList,FromDate,ToDate , and then loops with the id list and calls SP1 and union the results.
I hope I am clear...
This is the original SP, If you can make it accept UnitIMEIList it will also be great:
CREATE PROCEDURE [dbo].[GetGeneratorsReport]
#UnitIMEI varchar(15),
#DateFrom [datetime],
#DateTo [datetime]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #mycur CURSOR
DECLARE #GeneratorId int
DECLARE #FieldId int
DECLARE #SensorName nvarchar(50)
DECLARE #StateNO bit
DECLARE #ReadingDate [datetime]
DECLARE #Value bit
DECLARE #FirstRun bit
DECLARE #SDate [datetime]
DECLARE #UnitName nvarchar(50)
--SET #UnitIMEI='358484004085845'
SET #UnitName = (SELECT TOP 1 NickName FROM Vehicles WHERE UnitIEMI = #UnitIMEI)
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#GeneratorsTempTable')) BEGIN DROP TABLE #GeneratorsTempTable END
CREATE TABLE #GeneratorsTempTable (
SensorId int,
UnitIMEI varchar(15),
UnitName nvarchar(50),
SensorName nvarchar(50),
FromDate [datetime],
ToDate [datetime]
)
SET #mycur = CURSOR
FOR
SELECT 104+[GPIO], [Name], [StateNO]
FROM [VehicleTrack].[dbo].[UnitSensors]
WHERE [UnitIMEI]=#UnitIMEI AND Type=3
OPEN #mycur
FETCH NEXT FROM #mycur INTO #FieldId, #SensorName, #StateNO
WHILE ##FETCH_STATUS = 0
BEGIN
SET #FirstRun = 1
SET #SDate = NULL
DECLARE messageCur CURSOR
FOR
SELECT ProtocolMessages.Date, convert(bit, AdditionalReadings.Value) AS Value
FROM ProtocolMessages INNER JOIN
AdditionalReadings ON ProtocolMessages.Id = AdditionalReadings.MessageId
WHERE (ProtocolMessages.UnitIEMI = #UnitIMEI) AND AdditionalReadings.FieldId = #FieldId AND ProtocolMessages.Date >= #DateFrom AND ProtocolMessages.Date <= #DateTo
ORDER BY ProtocolMessages.Date
OPEN messageCur
FETCH NEXT FROM messageCur INTO #ReadingDate, #Value
WHILE ##FETCH_STATUS = 0
BEGIN
IF (#Value > 1)
SET #Value = #Value - 2
IF (#FirstRun = 1 AND #SDate IS NULL)
BEGIN -- the first run
SET #FirstRun = 0 -- flip the bit for all future runs
IF (#Value = #StateNO)
SET #SDate = #ReadingDate
END
ELSE -- all subsequent runs after the first
BEGIN
IF (#SDate IS NULL)
BEGIN
IF (#Value = #StateNO)
SET #SDate = #ReadingDate
END
ELSE
BEGIN
IF (#Value <> #StateNO)
BEGIN
-- Store
INSERT INTO #GeneratorsTempTable ([SensorId], [UnitIMEI], [UnitName], [SensorName] , [FromDate], [ToDate]) VALUES (#FieldId - 104, #UnitIMEI, #UnitName, #SensorName, #SDate, #ReadingDate)
SET #SDate = NULL
END
END
END
FETCH NEXT FROM messageCur INTO #ReadingDate, #Value
END
CLOSE messageCur
DEALLOCATE messageCur
IF (#Value = #StateNO)
BEGIN
INSERT INTO #GeneratorsTempTable ([SensorId], [UnitIMEI], [UnitName], [SensorName] , [FromDate], [ToDate]) VALUES (#FieldId - 104, #UnitIMEI, #UnitName, #SensorName, #SDate, GETUTCDATE())
END
FETCH NEXT FROM #mycur INTO #FieldId, #SensorName, #StateNO
END
DEALLOCATE #mycur
SELECT * FROM #GeneratorsTempTable
END
GO
Thanks
For the benefit of other google users :)
I did it all by myself !
I created a database named 'SandBox' for that.
Create a sample table :
USE [SandBox]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblStudentGrades](
[StudentGradeID] [bigint] IDENTITY(1,1) NOT NULL,
[StudentID] [bigint] NOT NULL,
[TestID] [bigint] NOT NULL,
[TestDate] [date] NOT NULL,
[TestGrade] [int] NULL
) ON [PRIMARY]
GO
Put some data (If you are lazy:) ) :
USE [SandBox]
GO
SET IDENTITY_INSERT [dbo].[tblStudentGrades] ON
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (1, 1, 1, CAST(0x6E390B00 AS Date), 60)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (2, 1, 2, CAST(0x70390B00 AS Date), 80)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (3, 2, 1, CAST(0x6E390B00 AS Date), 90)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (4, 2, 2, CAST(0x70390B00 AS Date), 100)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (5, 3, 1, CAST(0x6E390B00 AS Date), 95)
INSERT [dbo].[tblStudentGrades] ([StudentGradeID], [StudentID], [TestID], [TestDate], [TestGrade]) VALUES (6, 3, 2, CAST(0x0F230100 AS Date), 98)
SET IDENTITY_INSERT [dbo].[tblStudentGrades] OFF
Create the SP that accepts a single id:
* This is just a sample ... don't forget it - I know I can send multiple IDs as a parameter...
USE [SandBox]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spGetStudentGrades]
#StudentID bigint
AS
BEGIN
SELECT * FROM [SandBox].[dbo].[tblStudentGrades]
WHERE StudentID = #StudentID;
END
GO
Now for the new SP that will allow multiple execution of the above SP (exactly what I was looking for):
USE [SandBox]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[spGetMultiple]
#StudentIDList varchar(100)
AS
BEGIN
DECLARE #StudentID VARCHAR(10)
--------------------------------------------------
-- Create a temporary table to hold the results:
--------------------------------------------------
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..#tblTemporaryGrades')) BEGIN DROP TABLE #tblTemporaryGrades END
CREATE TABLE #tblTemporaryGrades (
StudentGradeID bigint,
StudentID bigint,
TestID bigint,
TestDate date,
TestGrade int
)
--------------------------------------------------
-- Add a comma to the end of the ID list,
-- so the last ID will be also included.
SET #StudentIDList = #StudentIDList + ',' ;
---------------------------------------------------
WHILE CHARINDEX(',', #StudentIDList) > 0
BEGIN
-- STEP 1 :
-- Extract the current StudentID we want to get from the original SP
SET #StudentID = SUBSTRING(#StudentIDList, 1, ( CHARINDEX(',', #StudentIDList) - 1 ))
PRINT '#StudentID = ' + #StudentID;
-- STEP 2 :
-- Gather the data using the original SP
INSERT INTO #tblTemporaryGrades EXEC spGetStudentGrades #StudentID
-- STEP 3 :
-- Update the student ID to exclude the last StudentID we worked with
SET #StudentIDList = SUBSTRING(#StudentIDList, CHARINDEX(',', #StudentIDList) + 1, LEN(#StudentIDList))
PRINT 'NEW #StudentIDList = ' + #StudentIDList;
END
SELECT * FROM #tblTemporaryGrades
END
GO
Feel like testing it ?
Go ahead:
USE [SandBox]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[spGetMultiple]
#StudentIDList = N'3,2,1'
SELECT 'Return Value' = #return_value
GO
Good luck all !

Sql Server Stored Procedure Case When in Update

I am new in stored procedures.
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
UPDATE MY_TABLE
SET
WHEN
(( ID ) > 1)
THEN
ID=#ID
,
NAME = #NAME
END
I try to use when then for update my ID and Name
If Id is greater than 1 i want to update otherwise no update.
How can i do it ms sql?
Any help will be appreciated.
Thanks.
I think this is what you are after:
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
UPDATE MY_TABLE
SET NAME = #NAME
WHERE ID = #ID
END
You do not need to check ID>1 since you are checking the equality with #ID. If you want to be sure that this doesn't happen if #ID <=1 then you may try the following:
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
IF #ID > 1
UPDATE MY_TABLE
SET NAME = #NAME
WHERE ID = #ID
END
I'm not sure exactly what you're trying to update. Are you trying to change the name on a user record with id = #ID?
ALTER PROCEDURE [dbo].[SP_MY_STORE_PROCEDURED]
(
#ID INT,
#NAME VARCHAR(50)
)
AS
BEGIN
UPDATE MY_TABLE
SET Name = #Name
WHERE Id = #ID and #ID > 1
END
This should do it.
ALTER PROCEDURE [dbo].[SP_MY_STORED_PROCEDURE] ( #ID INT, #NAME VARCHAR(50) )
AS
BEGIN
IF #ID > 1
UPDATE MY_TABLE
SET Name = #Name
WHERE Id = #ID
END

Storedprocedure to check the value already in the table

I have a stored procedure to insert values in to a table.Here I need to check the values for insert is already in the table .how can I check this in my stored procedure.here is my stored procedure.
USE [Databasse_sync]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[kt_getyoutubevideo]
#ProductID nvarchar(200),
#YoutubeUrl nvarchar(200),
#YoutubeImage nvarchar(200)
AS
INSERT INTO YoutubeVideo(ProductID,YoutubeUrl,YoutubeImage,DATASET)VALUES(#ProductID,#YoutubeUrl,#YoutubeImage,'DAT')
RETURN
Here I need to check the ProducId is same or not?If ProductId is same then Update otherwise Insert.>>>??
USE [Databasse_sync]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[kt_getyoutubevideo]
#ProductID nvarchar(200),
#YoutubeUrl nvarchar(200),
#YoutubeImage nvarchar(200)
AS
MERGE [YoutubeVideo] AS Y
USING (SELECT #ProductID,#YoutubeUrl, #YoutubeImage) AS SourceRow (ProductID,YoutubeUrl,YoutubeImage)
ON Y.[ProductID] = SourceRow.ProductID
WHEN MATCHED THEN
UPDATE SET
Y.[ProductID] = SourceRow.ProductID
,Y.[YoutubeUrl] = SourceRow.YoutubeUrl
,Y.[YoutubeImage] = SourceRow.YoutubeImage
WHEN NOT MATCHED THEN
INSERT (ProductID,YoutubeUrl, YoutubeImage, DATASET)
VALUES (SourceRow.ProductID,SourceRow.YoutubeUrl, SourceRow.YoutubeImage,'DAT');
RETURN
IF NOT EXISTS(SELECT TOP 1 ProductID FROM YoutubeVideo WHERE ProductID=#ProductID) BEGIN
--INSERT HERE
END
ELSE BEGIN
--UPDATE HERE
END
DECLARE #EXISTS BIT
SELECT #EXISTS = 1
WHERE EXISTS
(SELECT ID FROM YouTubeVideo
WHERE ID = #ProductID
AND YoutubeUrl = #YoutubeUrl)
IF #Exists = 1
BEGIN
-- Update
END
ELSE
BEGIN
-- INSERT
END
#Arun
ALTER PROCEDURE [dbo].[kt_getyoutubevideo]
#ProductID nvarchar(200),
#YoutubeUrl nvarchar(200),
#YoutubeImage nvarchar(200)
AS
BEGIN
DECLARE #counter INT
#counter=SELECT COUNT(ProductID) FROM YoutubeVideo WHERE ProductID=#ProductID
IF(#counter = 0)
BEGIN
INSERT INTO YoutubeVideo(ProductID,YoutubeUrl,YoutubeImage,DATASET)VALUES(#ProductID,#YoutubeUrl,#YoutubeImage,'DAT')
END
END
if u want to check record is inserted or not then u can take one out parameter and chek recored is inserted or not.
try this:
ALTER PROCEDURE [dbo].[kt_getyoutubevideo]
#ProductID nvarchar(200),
#YoutubeUrl nvarchar(200),
#YoutubeImage nvarchar(200)
AS BEGIN
DECLARE #counter int
#counter = SELECT count(ProductID) FROM YoutubeVideo WHERE ProductID=#ProductID
IF(#counter = 0)
BEGIN
INSERT INTO YoutubeVideo(ProductID,YoutubeUrl,YoutubeImage,DATASET)VALUES(#ProductID,#YoutubeUrl,#YoutubeImage,'DAT')
End
ELSE
begin
UPDATE SET
ProductID = #ProductID
,YoutubeUrl = #YoutubeUrl
,YoutubeImage = #YoutubeImage
END END