Для каждого в MS SQL SERVER?
У меня есть две таблицы:
Employees(EmployeeID, EmployeeName, EmployeeStatus, BasicSalary)
и
EmployeePayroll (PayrollID, EmployeeID, VoucherNo, BasicSalary, SalaryMonth)
Я хочу сделать цикл for each
для каждого сотрудника в первой таблице, чтобы я мог вставлять фиктивные данные, такие как (0, EmployeeID,0 ,0 ,0)
во вторую таблицу.
Я попытался сделать это с помощью цикла for
, но я не смог его сделать, так как существует цикл for each
в MS SQL Server?
Ответы
Ответ 1
Используйте следующий оператор:
INSERT INTO EmployeePayroll
SELECT
0,EmployeeID ,0,0,0
FROM
Employees
Вы можете проверить наличие записи перед ее добавлением, добавив:
WHERE
ID NOT IN
(
SELECT
EmployeeID
FROM
EmployeePayroll
)
Ответ 2
Если вам нужен действительно цикл, вы можете использовать курсор. Они ужасно неэффективны, поэтому вам следует избегать, если вы этого не требуете:
DECLARE c CURSOR READ_ONLY FAST_FORWARD FOR
SELECT EmployeeID
FROM Employees
DECLARE @id Int
-- Open the cursor
OPEN c
FETCH NEXT FROM c INTO @id
WHILE (@@FETCH_STATUS = 0)
BEGIN
INSERT INTO EmployeePayroll
SELECT 0, @id, 0, 0, 0
-- do other stuff
FETCH NEXT FROM c INTO @id
END
-- Close and deallocate the cursor
CLOSE c
DEALLOCATE c
Ответ 3
Это единственный способ достичь вашего требования, используя переменную таблицы While loop и Temp,
Пример запроса приведен ниже,
--: Get the Employees table data & insert this to temp table variable
Declare @TempEmpTbl Table (RowId int identity, EmployeeID int, EmployeeName nvarchar(100), EmployeeStatus int, BasicSalary int);
Insert into @TempEmpTbl Select * from Employees;
--: temp variables
Declare @TempEmpCount Int = (Select Count(RowId) From @TempEmpTbl);
Declare @MinCount Int = 1;
Declare @GetEmpId int;
--: while loop for EmployeePayroll tbl insertion based on Employees data
While(@TempEmpCount >= @MinCount)
Begin
Set @GetEmpId = (Select EmployeeID From @TempEmpTbl Where RowId = @MinCount);
Insert into EmployeePayroll values (0, @GetEmpId,0 ,0 ,0)
Set @MinCount = @MinCount + 1;
End
Примечание. Предположим, что запись сотрудника уже существует, мы можем обновлять записи EmployeePayroll из этого цикла while.
Ответ 4
INSERT INTO EmployeePayroll
SELECT
0,E.EmployeeID ,0,0,0
FROM
Employees E
WHERE
NOT EXISTS
(
SELECT
1
FROM
EmployeePayroll WHERE EmployeeID = E.Id
)
Надеюсь, что это поможет
Это наиболее оптимизированный способ достижения этого
Ответ 5
HI
USE Ограничения по умолчанию для столбца, который должен быть равен нулю
payrollID, VoucherNo, BasicSalary, Доход месяц
вставьте EmployeeID для того же и использовать вышеупомянутую концепцию
Ответ 6
Я искал достойный путь для цикла foreach в SQL и придумал этот простой код
SELECT RowNum = ROW_NUMBER() OVER(ORDER BY Id),*
INTO #Locations
FROM [dbo].[Location]
DECLARE @MaxRownum INT
SET @MaxRownum = (SELECT MAX(RowNum) FROM #Locations)
DECLARE @Iter INT
SET @Iter = (SELECT MIN(RowNum) FROM #Locations)
WHILE @Iter <= @MaxRownum
BEGIN
DECLARE @currentCountry varchar(250)
DECLARE @locId int
SET @currentCountry = ( SELECT Country
FROM #Locations
WHERE RowNum = @Iter)
SET @LocId = ( SELECT Id
FROM #Locations
WHERE RowNum = @Iter)
-- run your operation here
Update [dbo].[Location]
SET CountryId = (SELECT (Id) FROM [dbo].[Site] WHERE [dbo].[Site].Name = @currentCountry)
WHERE [dbo].[Location].Id = @locId
SET @Iter = @Iter + 1
END
DROP TABLE #Locations
Ответ 7
Попробуйте Cross Apply
. Это лучший альтернатив для курсора и цикла.
Перемещение, если вы сравните план выполнения креста, примените с другими методами, вы заметите его заметно быстрее
http://sqlserverplanet.com/sql-2005/cross-apply-explained