问题
I am trying to insert records into existing but empty table based on from date and to date parameters using cursor in stored procedure. Please let me know what I am doing wrong in the below SQL?
When executing this procedure I am getting first row duplicated multiple times.
Error:
Maximum stored procedure, function, trigger or view nesting level exceeded (limit32)
Code:
ALTER proc [dbo].[spempmaster] (@date1 datetime,@date2 datetime)
as
Begin
Set nocount on
declare @doj datetime
declare @empname nchar(10)
declare @managername nchar(10)
declare @dept varchar(50)
declare emp_report15 cursor for
select convert(varchar(10),convert(smalldatetime,emp.doj,120),103) DOJ,
(emp.name + ' ' + emp.lastname) Name,
emp1.name Manager_Name, txtdepartment Department
from empmaster emp
left outer join tbljobtitles jt
on emp.fkjobtitleid = jt.pkjobtitleid,
tbldepartment td,
tblteam t,
empmaster emp1
where
jt.fkteamid = t.pkteamid
and td.pkdeptid= t.fkdeptid
and emp.reportingto = emp1.empno
and emp.doj between @date1 and @date2
order by doj
open emp_report15
fetch emp_report15 into @doj, @empname, @managername, @dept
while @@fetch_status = 0
begin
insert into tblreport (DOJ,emp_name,manager_name,department)
values(@doj,@empname,@managername,@dept)
end
fetch next from emp_report15 into @doj,@empname,@managername,@dept
close emp_report15
deallocate emp_report15
end
回答1:
First of all - there's absolutely no need for a cursor in this situation. SQL Server is a set-based system - don't apply the procedural row-by-agonizing-row approach that works in procedural languages to this set-based system! Use a set-based approach instead!
Also: don't mix the proper ANSI join syntax with the old-style, deprecated comma-separated list of tables JOIN approach. That old style has been deprecated with the SQL-92 standard - more than 20 years ago! - about time to toss it out the window and use the proper ISO/ANSI standard JOIN syntax (INNER JOIN, LEFT OUTER JOIN) all the time.
So basically, in the end - your statement would be something like:
ALTER PROCEDURE [dbo].[spempmaster] (@date1 DATETIME, @date2 DATETIME)
AS
INSERT INTO dbo.tblreport(DOJ, emp_name, manager_name, department)
SELECT
CONVERT(VARCHAR(10), CONVERT(SMALLDATETIME, emp.doj, 120), 103),
(emp.name + ' ' + emp.lastname),
emp1.name Manager_Name,
txtDepartment
FROM
dbo.empmaster emp
INNER JOIN
dbo.empmaster emp1 ON emp.reportingto = emp1.empno
LEFT OUTER JOIN
dbo.tbljobtitles jt ON emp.fkjobtitleid = jt.pkjobtitleid
LEFT OUTER JOIN
dbo.tblteam t ON jt.fkteamid = t.pkteamid
LEFT OUTER JOIN
dbo.tbldepartment td ON td.pkdeptid = t.fkdeptid
WHERE
emp.doj BETWEEN @date1 AND @date2
As for avoiding duplicates: run your SELECT query separately, and see why you're getting duplicates. Just from this code alone, there's no way for outsiders to provide a meaningful answer here - it entirely depends on what data is stored in your tables.
来源:https://stackoverflow.com/questions/20311319/how-to-insert-value-to-table-using-cursor-in-stored-procedure-without-getting-du