【问题标题】:Returning Unique IDs from Oracle Update statement in VB.NET从 VB.NET 中的 Oracle Update 语句返回唯一 ID
【发布时间】:2019-01-29 14:55:33
【问题描述】:

我正在尝试更新我们用来处理消息的 Oracle 表中的一组行。因为这个表很忙,所以如果更新可以返回它在原子事务中更新的行的唯一ID,那将是最好的。我修改了在 StackOverflow 上找到的代码示例,如下所示,但是当我检查参数“p”时,我没有发现更新语句返回的任何信息,正如我所料。

对于修改设置 Oracle 调用的 .NET 代码或修改 Oracle SQL 语句本身有什么建议吗?

        Dim connectString As String = data source=ORA1;user id=MESSAGEBOX;password=MESSAGEBOX

    Dim conn As New OracleConnection(connectString)
    If conn.State <> ConnectionState.Open Then
        conn.Open()
    End If
    Dim transaction As OracleTransaction = conn.BeginTransaction()

    Dim cmd As New OracleCommand()
    cmd.Connection = conn

    cmd.CommandText = "BEGIN UPDATE MESSAGE_TABLE SET C_WAS_PROCESSED = 2 WHERE C_ID IN (SELECT * FROM(SELECT C_ID FROM MESSAGE_TABLE WHERE C_WAS_PROCESSED = 0 AND  C_CREATED_DATE_TIME < CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE)  ORDER BY C_MESSAGE_PRIORITY, C_ID) WHERE ROWNUM < 16)  RETURNING C_ID BULK COLLECT INTO :C_ID; END;"


    cmd.CommandType = CommandType.Text

    cmd.BindByName = True
    cmd.ArrayBindCount = 15

    Dim p As New OracleParameter()
    p.ParameterName = "C_ID"
    p.Direction = ParameterDirection.Output
    p.OracleDbType = OracleDbType.Int64
    p.Size = 15
    p.ArrayBindSize = New Integer() {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}
    p.CollectionType = OracleCollectionType.PLSQLAssociativeArray
    cmd.Parameters.Add(p)

    Dim nRowsAffected As Integer = cmd.ExecuteNonQuery()

    transaction.Commit()
    conn.Close()
    conn.Dispose()

【问题讨论】:

    标签: vb.net oracle


    【解决方案1】:

    我认为这里的问题是RETURNED BULK COLLECT INTO 的 SQL 变量需要是 TABLE 类型,而不是简单的数字类型。

    更改您的 SQL 以包含如下声明块:

    cmd.CommandText = "DECLARE TYPE IDS IS TABLE OF MESSAGE_TABLE.C_ID%TYPE; C_ID IDS; 
    BEGIN UPDATE MESSAGE_TABLE SET C_WAS_PROCESSED = 2 WHERE C_ID IN (SELECT * FROM(SELECT C_ID FROM MESSAGE_TABLE WHERE C_WAS_PROCESSED = 0 AND  C_CREATED_DATE_TIME < CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE)  ORDER BY C_MESSAGE_PRIORITY, C_ID) WHERE ROWNUM < 16)  RETURNING C_ID BULK COLLECT INTO :C_ID; END;"
    

    我从这个oracle-base.com 链接获得了表声明语法。

    【讨论】:

    • 这有效:DECLARE TYPE tReturn IS TABLE OF COR_INBOX_ENTRY.C_ID%TYPE; M_ID tReturn; BEGIN UPDATE COR_INBOX_ENTRY SET C_WAS_PROCESSED = 2 RETURNING C_ID BULK COLLECT INTO :M_ID; END; 但这不是UPDATE COR_INBOX_ENTRY SET C_WAS_PROCESSED = 2 WHERE C_ID &gt; 0 AND C_WAS_PROCESSED = 0 RETURNING C_ID BULK COLLECT INTO :M_ID 显然,如果您要更新的值是 WHERE 子句的一部分,ODP.NET 似乎不会处理返回任何内容。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多