Подтвердить что ты не робот

Для каждого в 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?

4b9b3361

Ответ 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