oracle 如何在同一行C#上执行2个SQLplus语句

avkwfej4  于 2023-03-29  发布在  Oracle
关注(0)|答案(2)|浏览(263)

我有一个可以在sqlplus上使用的过程,但在C#中,我不知道如何在cmd中编写execute。
这是我的命令sqlplus

CREATE OR REPLACE PROCEDURE get_column1 (p_MaritalStatus IN VARCHAR2,p_cursor out SYS_REFCURSOR)
as
BEGIN
   Open p_cursor for
   SELECT column_name FROM all_tab_columns WHERE table_name = p_MaritalStatus ORDER BY column_id;
   dbms_sql.return_result(p_cursor);
EXCEPTION
WHEN no_data_found THEN 
NULL;
 END;

VARIABLE cur REFCURSOR;
execute get_column1('V_$SGA',:cur);

C#

`OracleCommand cmd = con.CreateCommand();
cmd.CommandText = "VARIABLE cur REFCURSOR;execute get_column1('V_$SGA',:cur);";
cmd.CommandType = CommandType.StoredProcedure;
OracleDataReader dr = cmd.ExecuteReader();`
pbpqsu0x

pbpqsu0x1#

当您将CommandType设置为StoredProcedure时,这意味着CommandText仅包含存储过程的名称。类似于以下内容:

cmd.CommandText = "get_column1";
cmd.CommandType = CommandType.StoredProcedure;

你的命令不是一个存储过程。它是内联SQL。SQL调用一个存储过程的事实既不在这里也不在那里。只要去掉设置CommandType的行并接受默认的Text
我并不真正使用Oracle,所以我仍然不能100%确定它是否能处理由分号分隔的多个SQL语句,但它能处理SQL Server,所以我猜它会很好。
编辑:
根据下面的评论,你不能在一个命令中同时执行多个语句。在这种情况下,你可能会使用两个单独的命令或同一个命令两次,并在其间更改CommandText。你可能会想在一个事务中这样做。我所说的关于CommandType仍然有效。

a7qyws3x

a7qyws3x2#

Oracle禁止在一个命令中使用多个语句。这有助于防止SQL注入攻击。
对于您的用例,不要尝试在SQL中声明变量,请在C#中指定bind参数:

CREATE OR REPLACE PROCEDURE get_column1 (
  p_MaritalStatus IN  all_tab_columns.table_name%TYPE,
  p_cursor        OUT SYS_REFCURSOR
)
AS
BEGIN
   OPEN p_cursor FOR
     SELECT column_name
     FROM   all_tab_columns
     WHERE  table_name = p_MaritalStatus
     ORDER BY column_id;
END;
/

然后(未经测试,因为我没有C#连接的数据库,但它给了你一个大致的想法):

OracleCommand cmd = con.CreateCommand();
cmd.CommandText = "get_column1";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("P_MARITALSTATUS", OracleDbType.Char).Value = "V_$SGA";
cmd.Parameters.Add("P_CURSOR", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
OracleDataReader dr = cmd.ExecuteReader()

相关问题