- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我需要做的是将 C# DataTable 传递给 Oracle 存储过程。
这是我所做的:
甲骨文方面:
创建了一个类型:
create or replace TYPE CUSTOM_TYPE AS OBJECT
(
attribute1 VARCHAR(10),
attribute2 VARCHAR(10)
);
创建了一个表
create or replace TYPE CUSTOM_TYPE_ARRAY AS TABLE OF CUSTOM_TYPE;
创建了一个存储过程
create or replace PROCEDURE SP_TEST
(
P_TABLE_IN IN CUSTOM_TYPE_ARRAY,
P_RESULT_OUT OUT SYS_REFCURSOR
) AS
--P_TABLE_IN CUSTOM_TYPE_ARRAY;
BEGIN
OPEN P_RESULT_OUT FOR
SELECT attribute1, attribute2
FROM TABLE(P_TABLE_IN);
END SP_TEST;
C# 端:
void Run()
{
OracleConnection oraConn = new OracleConnection();
oraConn.ConnectionString = ConfigurationManager.ConnectionStrings["NafasV2ConnectionString"].ToString();
DataSet dataset = new DataSet();
DataTable Dt = new DataTable();
OracleDataAdapter da = new OracleDataAdapter();
OracleCommand cmd = new OracleCommand();
try
{
FormTVP(ref Dt);
PopulateTVP(ref Dt);
oraConn.Open();
cmd.Connection = oraConn;
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "SP_TEST";
OracleParameter parm1 = new OracleParameter("P_TABLE_IN", OracleDbType.RefCursor,100,"xx");
parm1.Value = Dt;
parm1.Direction = ParameterDirection.Input;
cmd.Parameters.Add(parm1);
OracleParameter parm2 = new OracleParameter("P_RESULT_OUT", OracleDbType.RefCursor);
parm2.Direction = ParameterDirection.Output;
cmd.Parameters.Add(parm2);
da.SelectCommand = cmd;
da.Fill(dataset);
ASPxLabel1.Text = "OK!!";
}
catch (Exception ex)
{
ASPxLabel1.Text = "DIE. REASON: " + ex.Message;
}
finally
{
da.Dispose();
cmd.Dispose();
oraConn.Close();
oraConn.Dispose();
}
}
void FormTVP(ref DataTable Dt)
{
DataColumn attribute1 = Dt.Columns.Add("ATTRIBUTE1", typeof(String));
DataColumn attribute2 = Dt.Columns.Add("ATTRIBUTE2", typeof(String));
Dt.AcceptChanges();
}
void PopulateTVP(ref DataTable Dt)
{
DataRow Dr = Dt.NewRow();
Dr["ATTRIBUTE1"] = "MK1";
Dr["ATTRIBUTE2"] = "MK2";
Dt.Rows.Add(Dr);
DataRow Dr1 = Dt.NewRow();
Dr1["ATTRIBUTE1"] = "HH1";
Dr1["ATTRIBUTE2"] = "HH2";
Dt.Rows.Add(Dr1);
Dt.AcceptChanges();
}
但是我得到一个错误:
Invalid parameter binding Parameter name: P_TABLE_IN
帮助!
最佳答案
不能直接绑定(bind)DataTable。您需要为要从 .NET 访问的任何 UDT 创建自定义类。这里我做了一个简单的例子,如何以半通用的方式将 DataTable 映射到 UDT:
void Main()
{
var dataTable = BuildSourceData();
using (var connection = new OracleConnection("DATA SOURCE=hq_pdb_tcp;PASSWORD=oracle;USER ID=HUSQVIK"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "BEGIN HUSQVIK.SP_TEST(:P_TABLE_IN, :P_RESULT_OUT); END;";
command.BindByName = true;
var p1 = command.CreateParameter();
p1.ParameterName = "P_TABLE_IN";
p1.OracleDbType = OracleDbType.Array;
p1.UdtTypeName = "HUSQVIK.CUSTOM_TYPE_ARRAY";
p1.Value = ConvertDataTableToUdt<CustomTypeArray, CustomType>(dataTable);
command.Parameters.Add(p1);
var p2 = command.CreateParameter();
p2.Direction = ParameterDirection.Output;
p2.ParameterName = "P_RESULT_OUT";
p2.OracleDbType = OracleDbType.RefCursor;
command.Parameters.Add(p2);
command.ExecuteNonQuery();
using (var reader = ((OracleRefCursor)p2.Value).GetDataReader())
{
var row = 1;
while (reader.Read())
{
Console.WriteLine($"Row {row++}: Attribute1 = {reader[0]}, Attribute1 = {reader[1]}");
}
}
}
}
}
private DataTable BuildSourceData()
{
var dataTable = new DataTable("CustomTypeArray");
dataTable.Columns.Add(new DataColumn("Attribute1", typeof(string)));
dataTable.Columns.Add(new DataColumn("Attribute2", typeof(string)));
dataTable.Rows.Add("r1 c1", "r1 c2");
dataTable.Rows.Add("r2 c1", "r2 c2");
return dataTable;
}
public static object ConvertDataTableToUdt<TUdtTable, TUdtItem>(DataTable dataTable) where TUdtTable : CustomCollectionTypeBase<TUdtTable, TUdtItem>, new() where TUdtItem : CustomTypeBase<TUdtItem>, new()
{
var tableUdt = Activator.CreateInstance<TUdtTable>();
tableUdt.Values = (TUdtItem[])tableUdt.CreateArray(dataTable.Rows.Count);
var fields = typeof(TUdtItem).GetFields();
for (var i = 0; i < dataTable.Rows.Count; i++)
{
var itemUdt = Activator.CreateInstance<TUdtItem>();
for (var j = 0; j < fields.Length; j++)
{
fields[j].SetValue(itemUdt, dataTable.Rows[i][j]);
}
tableUdt.Values[i] = itemUdt;
}
return tableUdt;
}
[OracleCustomTypeMapping("HUSQVIK.CUSTOM_TYPE_ARRAY")]
public class CustomTypeArray : CustomCollectionTypeBase<CustomTypeArray, CustomType>
{
}
[OracleCustomTypeMapping("HUSQVIK.CUSTOM_TYPE")]
public class CustomType : CustomTypeBase<CustomType>
{
[OracleObjectMapping("ATTRIBUTE1")]
public string Attribute1;
[OracleObjectMapping("ATTRIBUTE2")]
public string Attribute2;
public override void FromCustomObject(OracleConnection connection, IntPtr pointerUdt)
{
OracleUdt.SetValue(connection, pointerUdt, "ATTRIBUTE1", Attribute1);
OracleUdt.SetValue(connection, pointerUdt, "ATTRIBUTE2", Attribute2);
}
public override void ToCustomObject(OracleConnection connection, IntPtr pointerUdt)
{
Attribute1 = (string)OracleUdt.GetValue(connection, pointerUdt, "ATTRIBUTE1");
Attribute2 = (string)OracleUdt.GetValue(connection, pointerUdt, "ATTRIBUTE2");
}
}
public abstract class CustomCollectionTypeBase<TType, TValue> : CustomTypeBase<TType>, IOracleArrayTypeFactory where TType : CustomTypeBase<TType>, new()
{
[OracleArrayMapping()]
public TValue[] Values;
public override void FromCustomObject(OracleConnection connection, IntPtr pointerUdt)
{
OracleUdt.SetValue(connection, pointerUdt, 0, Values);
}
public override void ToCustomObject(OracleConnection connection, IntPtr pointerUdt)
{
Values = (TValue[])OracleUdt.GetValue(connection, pointerUdt, 0);
}
public Array CreateArray(int numElems)
{
return new TValue[numElems];
}
public Array CreateStatusArray(int numElems)
{
return null;
}
}
public abstract class CustomTypeBase<T> : IOracleCustomType, IOracleCustomTypeFactory, INullable where T : CustomTypeBase<T>, new()
{
private bool _isNull;
public IOracleCustomType CreateObject()
{
return new T();
}
public abstract void FromCustomObject(OracleConnection connection, IntPtr pointerUdt);
public abstract void ToCustomObject(OracleConnection connection, IntPtr pointerUdt);
public bool IsNull
{
get { return this._isNull; }
}
public static T Null
{
get { return new T { _isNull = true }; }
}
}
函数 ConvertDataTypeToUdt 是通用的,如果您提供适当的类,它会自动映射数据表。下一步将完全自动化映射,以便目标数据类型将由数据表本身定义。自定义类型属性中的“HUSQVIK”是架构名称,如果您不作为包含自定义类型的架构所有者进行连接,则它必须对应于您的数据库。
关于C# DataTable 到 Oracle 存储过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31890745/
该插件的绝大多数文档表明您可以使用 对其进行初始化 $('#example').dataTable(); 但是http://www.datatables.net/examples/api/multi_
我有一个 SQL 查询,它获取一些数据(dbtable 表中的语言列)。查询使用 GROUP_CONCAT,因此一个单元格有多个结果,例如 "Ajax, jQuery, HTML, CSS". 我想要
我有一个由 jQuery DataTables 增强的动态表,它显示一个与此类似的自定义对象 example . JSON: { "data": [ { "name": "Ti
我有两个数据表。首先是 DataTable NameAddressPhones = new DataTable(); 具有三列姓名、地址和电话号码。但我只想要两列姓名和地址数据,所以我想将这些列(包含
有没有办法将“处理...”语言放在 DataTable 对象的顶部而不是垂直中间?如果我有一张长 table ,它会隐藏在页面之外,因为它的默认位置在中间。 $('#example').dataTab
当我们向 DataTables 添加自定义过滤器时: $.fn.dataTable.ext.search.push(function(settings, data, dataIndex) { ..
我可以更改 dataTables 中搜索文本字段的宽度吗? 我现在正在编写以下代码,但它不起作用。 $('#example').dataTable() .columnFilter(
使用 DataTables plugin 时 如何使分页和 Showing 1 to 8 of 8 entries 出现在顶部而不是底部? 谢谢 最佳答案 每个数据表控件都以唯一的 id 命名计划之后
Angular 版本:6.0.4 ~ 节点版本:10.4.1 ~ NPM 版本:6.1.0 我看到这个问题被问了很多次,但没有回答。 关注这些后instructions to install angu
当单击外部按钮时,我正在尝试使用 DataTable(新版本)修改单元格值。我现在有以下内容: $(document).on('click', '.dropdown-menu li a', funct
引用:http://datatables.net/reference/api/page.info() 我正在尝试获取 ajax POST 生成的 jQuery DataTable 的当前分页信息。 使
以下对我有用: $('#datatable').on('page.dt', function() { alert("changed"); }); 每当我更改页面时,都会显示警报。但是如果我想警
我有一个 HTML 表,我在其中应用了 DataTables 函数。我使用表的第一行并将"template"类应用为我的模板行。然后选择此格式并使用 JSON feed 填充表中的所有行。问题是 Da
我有一个由 DataTables 1.10 驱动的表。过滤已打开。当我在下面谈论“做搜索”时,我指的是使用该表的过滤功能。 问题描述 关闭 stateSave 一切正常。但是,当 stateSave
看看这个例子,http://www.datatables.net/examples/api/multi_filter_select.html ,它使用 DataTable API 中的 columns
我正在使用 jQuery DataTables 在 spring 4.x 应用程序中创建一个报表页面来呈现报表。 通过 Jackson 消息转换器解析后,服务器返回以下对象。 { "data"
我在刷新 Primesfaces 的延迟加载数据表时遇到了一些问题。我正在使用 3.0.M4。 使用过滤器在您的示例中使用三个类。还尝试了仅使用延迟加载的示例,但随后未在 Controller 中重新
在 Blue Prism (BP) 中,有一种叫做 Collection 的东西,它基本上是 C# 中的 DataTable。在 BP 中,您可以在集合中拥有集合。我的问题是,您可以在 C# 的 Da
我正在使用 Flutter DataTables 来显示购物车中的商品列表。现在我想编辑任何选定行的数量。有没有办法获取用户点击的行信息? 以下是我的DataTable的完整代码: class _Da
我有一个关于 primefaces 数据表组件的问题。我想将 DataTable 变量绑定(bind)到 p:dataTable,以便我能够从支持 bean 以编程方式操作第一个、行、rowsPerP
我是一名优秀的程序员,十分优秀!