许多插入在开始端块内

时间:2017-03-27 08:55:00

标签: sql sql-server tsql sql-server-express

我有一个包含超过150k行语句的sql脚本(大多数是插入)。我只想在表为空时执行这些插入:

IF EXISTS (SELECT * FROM [MyTable])
BEGIN
    PRINT 'No need to insert data'
    --Stop executing script
END
ELSE
BEGIN
    --INSERT #1
    --...
    --Insert #150000
END

问题:似乎ELSE块太大了。我尝试使用GO,但它在BEGIN-END块内部不起作用。我该如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

要对抗巨大的其他区块,您可以使用以下3种策略中的任何一种。

STRATEGY 1

使用SQL Server中的批量插入。只需将所有数据转储到csv文件中,然后在else块中使用以下语句。将csv文件存储在您的计算机上,并在下面的FROM语句中提供它的UNC路径。这样,你的else块中只有一行。

BULK INSERT dbo.MyTable
FROM '\\share\somepath\myTableInsertData.csv'
WITH (FORMAT = 'CSV'); 

STRATEGY 2

编写一次只插入x行的存储过程。然后,您可以在While loop中调用此存储过程,并且您的else块将非常小。您可以在原始SQL的while循环中重复调用此存储过程,然后else块将只是几行t-sql代码。

请注意,您可以通过使用变量@numberOfRowsAtaTime的适当值来控制存储过程一次插入的行数。我已经使用了1000,所以在一次存储过程调用中插入了1000行。

当然,根据您的业务规则,您可以编写存储过程的insert语句的脚本。如果您的INSERTS中有一个模式,那么您可以将该模式编写到下面的存储过程逻辑中。

存储过程

CREATE PROCEDURE dbo.insertXRows
    @startIndex INT,
    @numberOfRows INT 
AS
BEGIN

    SET NOCOUNT ON;

    DECLARE @counter INT;
    SET @counter = @startIndex;

    WHILE @counter < (@startIndex + @numberOfRows -1)
    BEGIN 
    -- Insert statements for rows goes here
    --INSERT FOR @counter -- @counter would be different for each iteration
      SET @counter =  @counter + 1;
    END
END
GO

您的SQL

IF EXISTS (SELECT * FROM [MyTable])
BEGIN
    PRINT 'No need to insert data'
    --Stop executing script
END
ELSE
BEGIN

    declare @insertRowCounter int;
    set @insertRowCounter = 1;
    declare @numberOfRowsAtaTime int;
    set @numberOfRowsAtaTime = 1000;
    WHILE @insertRowCounter <= 150000
      EXEC dbo.insertXRows @insertRowCounter, @numberOfRowsAtaTime -- insert 1000 rows at a time
      SET @insertRowCounter = @insertRowCounter + @numberOfRowsAtaTime; 
    END
END

STRATEGY 3

提出10个存储过程,以便每个存储过程有15000个INSERTS。然后只需从你的else块中调用这10个存储过程。

10个存储过程

CREATE PROCEDURE dbo.insertProc1
  AS
BEGIN

    SET NOCOUNT ON;

    --INSERT1
    --INSERT2

     --INSERT15000

    END
END
GO



CREATE PROCEDURE dbo.insertProc2
  AS
BEGIN

    SET NOCOUNT ON;

    --INSERT15001
    --INSERT15002

     --INSERT3000

    END
END
GO

您的SQL

IF EXISTS (SELECT * FROM [MyTable])
BEGIN
    PRINT 'No need to insert data'
    --Stop executing script
END
ELSE
BEGIN
   EXEC insertProc1
   EXEC insertProc2
   EXEC insertProc3
   EXEC insertProc4
   EXEC insertProc5
   EXEC insertProc6
   EXEC insertProc7
   EXEC insertProc8
   EXEC insertProc9
   EXEC insertProc10
END

答案 1 :(得分:1)

您可以使用NOEXEC

create table T (ID int not null)
go
if 1=1
begin
    set noexec on
end
go
insert into T(ID) values (1),(2),(3)
--Repeat more inserts
go
set noexec off
go
select * from T

只打印一张空表 - 希望你能看到它如何适应你的脚本。

答案 2 :(得分:1)

难道你不能简单地在大脚本的开头添加这个块,而不构造else begin ... end吗?

IF EXISTS (SELECT * FROM [MyTable])
BEGIN
    PRINT 'No need to insert data'
    --Stop executing script and return
    RETURN
END
--Your old script starts here

答案 3 :(得分:0)

如何使用GOTO语句跳出插入语句?

IF EXISTS (SELECT * FROM [MyTable])
BEGIN
    GOTO NODATA
END

--INSERT #1
--...
--Insert #150000

NODATA:
    PRINT 'No need to insert data'