简体   繁体   English

在系统中,通过“ ExecuteReader”执行的多个SQL命令我只能操作SQL语句

[英]Multiple SQL commands executed via “ExecuteReader” in a system I can only manipulate SQL statements

I have to configure a system which provides me with an area to input SQL statements. 我必须配置一个为我提供输入SQL语句的区域的系统。

It is important to notice that we cannot modify the system we are configuring. 请务必注意,我们无法修改正在配置的系统。

I believe the system was built in C# (.net for sure but C# is a guess). 我相信系统是用C#构建的(肯定是.net,但C#是一个猜测)。

Any way, I'm trying to create a script that would: 无论如何,我正在尝试创建一个脚本,该脚本将:

  1. create a temporary table 创建一个临时表
  2. create a temporary procedure (which inserts into the table created) 创建一个临时过程(它将插入到创建的表中)
  3. call the temporary procedure 4 times 调用临时程序4次
  4. Read the temp table as a response to the system's call. 读取临时表作为对系统调用的响应。

Something like: 就像是:

CREATE Procedure #myTempProcedure(
  @param1 nvarchar(max)
) as 
begin
  insert #tempTable (col1, col2) select aCol, bCol from table2 where col2 = @param1;
end;


CREATE TABLE #tempTable
(col1 nvarchar(512),
(col2 nvarchar(512));

EXEC #myTempProcedure N'val1';
EXEC #myTempProcedure N'val2';
EXEC #myTempProcedure N'val3';
EXEC #myTempProcedure N'val4';

select col1, col2 from #tempTable;

The system is very likely executing my script via C# SqlCommand.ExecuteReader() method. 系统很可能通过C# SqlCommand.ExecuteReader()方法执行我的脚本。 As I can simulate the problem in a simple C# application I created. 因为我可以在我创建的简单C#应用程序中模拟问题。

The problem is that when executing this script, the system (or SQL Server) assumes the procedure body to be the entire script and seems to disregard my ; 问题在于,执行该脚本时,系统(或SQL Server)假定过程主体为整个脚本,并且似乎无视my ; in line 6 of the example above. 在上面示例的第6行中。 My intention with this ; 我的目的是这样; was to flag the end of the procedure creation. 标志着过程创建的结束。

Executing this script in Management studio requires a GO to be placed in line 7 of the example above, otherwise the same problem reported by the system would happen in Management Studio. 在Management Studio中执行此脚本需要将GO放置在上面示例的第7行中,否则系统报告的相同问题将在Management Studio中发生。

Is there a GO equivalent I could use in this script to get it to work?? 我可以在此脚本中使用GO等效功能使其正常工作吗?

Or is there a better way to script this?? 还是有更好的方法编写脚本?

I have a background in Oracle, and I'm still leaning SQL server usual tricks... The System accepts multiple commands apart from the create procedure here, So I'm inclined to believe there is a SQL Server trick I could use here. 我具有Oracle的背景,并且仍在使用SQL Server的常用技巧...除了此处的创建过程之外,系统还接受多个命令,因此我倾向于相信这里可以使用SQL Server的技巧。

Thank you in advance! 先感谢您!

The problem is that syntactically there is no way to create a procedure and then do something after it in the same batch. 问题是,从语法上讲,没有方法可以创建一个过程,然后再在同一批处理中执行某些操作。 The compiler doesn't know where it ends, and things like semi-colon don't fix it (because semi-colon only terminates a statement, not a batch). 编译器不知道它的结尾,分号之类的东西也无法解决(因为分号只能终止一条语句,而不能终止批处理)。

Using dynamic SQL, (and fixing one syntax error) this works: 使用动态SQL(并修复一个语法错误)可以起作用:

EXEC('
    CREATE Procedure ##myTempProcedure(
        @param1 nvarchar(max)
    ) as 
    begin
      insert #tempTable (col1, col2) select aCol, bCol from table2 where col2 = @param1;
    end;
');


CREATE TABLE #tempTable
(
    col1 nvarchar(512),
    col2 nvarchar(512)
);

EXEC ##myTempProcedure N'val1';
EXEC ##myTempProcedure N'val2';
EXEC ##myTempProcedure N'val3';
EXEC ##myTempProcedure N'val4';

select col1, col2 from #tempTable;

EXEC('DROP PROC ##myTempProcedure;');

1) please look at the rights on the server you many have some issues with if you cannot change or add anything to the system. 1)如果您无法更改或向系统添加任何内容,请查看许多人在服务器上存在的权利。 ie., Create procedure statements. 即,创建过程语句。

2) you could do a small exercise 2)你可以做些小运动

open a connection object using the SqlConnection() keep the connection open till you execute all you statements 使用SqlConnection()打开连接对象,使连接保持打开状态,直到执行所有语句为止

ie., a) create your #table b) execute your insert statement. 即a)创建您的#table b)执行您的insert语句。 c) select * from your #table this should get you back the data you are intending to get back from your temp table note i skipped the entire proc here. c)从#table中选择*,这应该可以使您从临时表中获取要恢复的数据注意,我在这里跳过了整个过程。

Instead of creating stored procedure, you can execute sql statements delimited by semi colon. 您可以执行以半冒号分隔的sql语句,而不是创建存储过程。 You can execute multiple statements this way. 您可以通过这种方式执行多个语句。 Also if you want to create a temp table and load it with data, you can use the same connection with multiple sql commands. 另外,如果要创建临时表并向其加载数据,则可以将同一连接与多个sql命令一起使用。

Given that the proc definition doesn't change, and that there is no real harm in the proc existing beyond the end of this particular process, it could just as easily be a regular (ie non-temporary) Stored Procedure that just happens to exist in tempdb . 鉴于proc的定义没有改变, 并且在此特定过程结束后proc中不存在任何实际危害,因此它很可能只是正好存在的常规(即非临时)存储过程在tempdb The benefit of using a regular Stored Procedure created in tempdb is that you do not need to worry about potential name collisions when using global temporary stored procedures. 使用在tempdb创建的常规存储过程的好处是,使用全局临时存储过程时,您不必担心潜在的名称冲突。 The script simply needs to ensure that the stored procedure exists. 该脚本仅需要确保存储过程存在。 But there is no need to remove the Stored Procedure manually or have it automatically cleaned up. 但是无需手动删除存储过程或自动清理存储过程。

The following code is adapted from @RBarryYoung's answer : 以下代码改编自@RBarryYoung的答案

IF (OBJECT_ID(N'tempdb.dbo.myTempProcedure') IS NULL)
BEGIN
  USE [tempdb];

  EXEC('
      CREATE PROCEDURE dbo.myTempProcedure(
          @param1 NVARCHAR(MAX)
      ) AS 
      BEGIN
        INSERT INTO #tempTable (col1, col2)
          SELECT aCol, bCol
          FROM table2
          WHERE col2 = @param1;
      END;
');
END;

CREATE TABLE #tempTable
(
    col1 NVARCHAR(512),
    col2 NVARCHAR(512)
);

EXEC tempdb.dbo.myTempProcedure N'val1';
EXEC tempdb.dbo.myTempProcedure N'val2';
EXEC tempdb.dbo.myTempProcedure N'val3';
EXEC tempdb.dbo.myTempProcedure N'val4';

SELECT col1, col2 FROM #tempTable;

The only difference here is that a non-temporary Stored Procedure does not execute in the context of the current database, but instead, like any other non-temporary Stored Procedure, runs within the context of the database where it exists, which in this case is tempdb . 唯一的区别是,非临时存储过程不会在当前数据库的上下文中执行,而是像其他任何非临时存储过程一样,在存在该数据库的上下文中运行,在这种情况下是tempdb So the table that is being selected from (ie table2 ) needs to be fully-qualified. 因此,从中选择的表(即table2 )需要完全合格。 This means that if the proc needs to run in multiple databases and reference objects local to each of them, then this approach is probably not an option. 这意味着,如果proc需要在多个数据库中运行并引用每个数据库的本地对象,则此方法可能不是一种选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM