ओपी शायद लंबे समय से इस मुद्दे को हल कर चुका है, लेकिन लेखन के समय के अनुसार, इस प्रश्न का केवल एक ही उत्तर है और यह वास्तव में डैपर के QueryMultiple()
का उपयोग करने की समस्या को हल नहीं करता है। ओरेकल के साथ विधि। जैसा कि @ कमोलास81 सही ढंग से बताता है, आधिकारिक उदाहरणों से सिंटैक्स का उपयोग करके, किसी को वास्तव में ORA-00933: SQL command not properly ended
मिलेगा। त्रुटि संदेश। मैंने QueryMultiple()
करने के तरीके के बारे में कुछ प्रकार के दस्तावेज़ों की खोज में कुछ समय बिताया ओरेकल के साथ, लेकिन मुझे आश्चर्य हुआ कि वास्तव में एक जगह नहीं थी जिसका उत्तर था। मैंने सोचा होगा कि यह काफी सामान्य कार्य है। मैंने सोचा था कि मैं <स्ट्राइक>मुझेस्ट्राइक> को बचाने के लिए यहां एक उत्तर पोस्ट करूंगा :) किसी को भविष्य में कुछ समय बस अगर किसी को भी यही समस्या होती है।
ऐसा लगता है कि डैपर सीधे ADO.NET के साथ SQL कमांड को पास करता है और जो भी डीबी प्रदाता कमांड निष्पादित कर रहा है। उदाहरणों से सिंटैक्स में, जहां प्रत्येक कमांड को लाइन ब्रेक द्वारा अलग किया जाता है, SQL सर्वर व्याख्या करेगा कि डेटाबेस के खिलाफ चलने के लिए कई क्वेरीज़ के रूप में और यह प्रत्येक क्वेरी को चलाएगा और परिणामों को अलग-अलग आउटपुट में वापस कर देगा। मैं ADO.NET विशेषज्ञ नहीं हूं, इसलिए मैं शब्दावली को गड़बड़ कर सकता हूं, लेकिन अंतिम प्रभाव यह है कि डैपर को कई क्वेरी आउटपुट मिलते हैं और फिर अपना जादू काम करते हैं।
ओरेकल, हालांकि, कई प्रश्नों को नहीं पहचानता है; यह सोचता है कि SQL कमांड विकृत है और ORA-00933
. लौटाता है संदेश। समाधान कर्सर का उपयोग करना और आउटपुट को डायनामिक पैरामीटर संग्रह में वापस करना है। उदाहरण के लिए, जबकि SQL सर्वर संस्करण इस तरह दिखेगा:
var sql =
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";
क्वेरी के Oracle संस्करण को इस तरह दिखने की आवश्यकता होगी:
var sql = "BEGIN OPEN :rslt1 FOR SELECT * FROM customers WHERE customerid = :id; " +
"OPEN :rslt2 FOR SELECT * FROM orders WHERE customerid = :id; " +
"OPEN :rslt3 FOR SELECT * FROM returns Where customerid = :id; " +
"END;";
SQL सर्वर के विरुद्ध चलने वाले प्रश्नों के लिए, डैपर इसे वहां से संभाल सकता है। हालांकि, क्योंकि हम परिणाम सेट को कर्सर पैरामीटर में वापस कर रहे हैं, हमें IDynamicParameters
का उपयोग करने की आवश्यकता होगी आदेश के लिए पैरामीटर निर्दिष्ट करने के लिए संग्रह। एक अतिरिक्त शिकन जोड़ने के लिए, सामान्य DynamicParameters.Add()
Dapper में विधि वैकल्पिक dbType पैरामीटर के लिए System.Data.DbType का उपयोग करती है, लेकिन क्वेरी के लिए कर्सर पैरामीटर Oracle.ManagedDataAccess.Client.OracleDbType.RefCursor
प्रकार के होने चाहिए . इसे हल करने के लिए, मैंने उस समाधान का उपयोग किया जिसे @Daniel Smith ने this answer
में प्रस्तावित किया था। और IDynamicParameters
. का एक कस्टम कार्यान्वयन बनाया इंटरफ़ेस:
using Dapper;
using Oracle.ManagedDataAccess.Client;
using System.Data;
public class OracleDynamicParameters : SqlMapper.IDynamicParameters
{
private readonly DynamicParameters dynamicParameters = new DynamicParameters();
private readonly List<OracleParameter> oracleParameters = new List<OracleParameter>();
public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction, object value = null, int? size = null)
{
OracleParameter oracleParameter;
if (size.HasValue)
{
oracleParameter = new OracleParameter(name, oracleDbType, size.Value, value, direction);
}
else
{
oracleParameter = new OracleParameter(name, oracleDbType, value, direction);
}
oracleParameters.Add(oracleParameter);
}
public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction)
{
var oracleParameter = new OracleParameter(name, oracleDbType, direction);
oracleParameters.Add(oracleParameter);
}
public void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
((SqlMapper.IDynamicParameters)dynamicParameters).AddParameters(command, identity);
var oracleCommand = command as OracleCommand;
if (oracleCommand != null)
{
oracleCommand.Parameters.AddRange(oracleParameters.ToArray());
}
}
}
तो सभी कोड एक साथ कुछ इस प्रकार हैं:
using Dapper;
using Oracle.ManagedDataAccess.Client;
using System.Data;
int selectedId = 1;
var sql = "BEGIN OPEN :rslt1 FOR SELECT * FROM customers WHERE customerid = :id; " +
"OPEN :rslt2 FOR SELECT * FROM orders WHERE customerid = :id; " +
"OPEN :rslt3 FOR SELECT * FROM returns Where customerid = :id; " +
"END;";
OracleDynamicParameters dynParams = new OracleDynamicParameters();
dynParams.Add(":rslt1", OracleDbType.RefCursor, ParameterDirection.Output);
dynParams.Add(":rslt2", OracleDbType.RefCursor, ParameterDirection.Output);
dynParams.Add(":rslt3", OracleDbType.RefCursor, ParameterDirection.Output);
dynParams.Add(":id", OracleDbType.Int32, ParameterDirection.Input, selectedId);
using (IDbConnection dbConn = new OracleConnection("<conn string here>"))
{
dbConn.Open();
var multi = dbConn.QueryMultiple(sql, param: dynParams);
var customer = multi.Read<Customer>().Single();
var orders = multi.Read<Order>().ToList();
var returns = multi.Read<Return>().ToList();
...
dbConn.Close();
}