OLEDB自定义编码 [英] OLEDB custom encoding

查看:194
本文介绍了OLEDB自定义编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标



我需要创建以特定格式.dbf文件,由客户指定。格式是的dBASE III的.dbf与kamenicky编码,使用整型,各种长度和双列类型的字符。



问题



我得到了几乎所有的工作,而且二者之间只有一个障碍:织补编码拒绝工作,尽管具体的转换表被写入该开关与兼容原来的字符kamenicky编码。这意味着输出文件结束了,例如,用于将其指定为进口串中的A0的十六进制值的炭FF的十六进制值。



如果您是打算(-1)的问题,我将不胜感激,为什么你在评论这样的信息 - 即使是你不明白的问题,充分将是很大的帮助,因为我想知道在哪里继续我的研究(如,在非常基础在这种情况下)



我都有种,排序的解决了这个问题(见注释),但解决的办法是有缺陷的,并没有按'T真正回答给定的问题都没有。





如何我说服Jet.OLEDB提供商不乱用编码?



有什么我试过




  • 使用FoxPro的供应商,这实际上工作得很好,除了小细节,我的客户的软件无法读取产生的.dbf文件。


  • 在插入数据,而无需使用OleDbParameter(这样的投入将不会被正确地转义)无济于事


  • 设置通过字符集= xxx和一些其他的连接字符串修改,我不太记得,现在,每一个A0的输出导致FF时间几个不同的编码。


  • 我已经找到了AutoTranslate属性在这里 ,但据我可以告诉它仅适用于SQL连接为Jet.OLEDB一直给我一个ISAM错误。


  • 我试图与周围的玩弄< A HREF =htt​​p://stackoverflow.com/questions/1475821/how-can-i-specify-the-character-encoding-to-be-used-by-oledb-when-querying-a-dbf>全球化设置,并没有多大帮助。




某些代码



连接字符串:

 供应商= Microsoft.Jet.OLEDB.4.0 ;数据源= {0};扩展属性= \的dBASE III; \; 



然后数据被使用的OleDbCommand插入,与正在充满OleDbParameter类和构建插入串的单个细胞可能会觉得很窝囊,但这里的代码:

 私人无效insertRows(T []的数据,OleDbConnection的连接)
{
使用(OleDbCommand的命令= connection.CreateCommand())
{$ b $为b(INT I = 0; I&下; data.Count();我++)
{
constructParams(数据由[i],I,命令);
command.CommandText = constructInsert(ⅰ,_filename);

command.ExecuteNonQuery();
}
}
}

私人无效constructParams(T数据,INT指数,OleDbCommand的命令)
{
command.Parameters.Clear();
的foreach(的PropertyInfo道具在_props)
{
如果(_cols.ContainsKey(prop.Name))
{
command.Parameters.Add(新OleDbParameter(@+ prop.Name +指数,prop.GetValue(数据)));
}
}
}

私人字符串constructInsert(INT dataNum,串tableName值)
{
线插入=INSERT INTO [ + tableName值+(;在_cols.Keys
的foreach(字符串键)
{
插入+ =[+键+];
$} b $ b将= insert.Remove(insert.Length - 1);
插入+ =)VALUES;

插入+ =(;
的foreach(字符串_cols.Keys键)
{
插入+ =@+按键+ dataNum +, ;
}

将= insert.Remove(insert.Length - 1);
插入+ =);;

插入的回报;
}


解决方案

下面是一个快速的东西,我尝试,似乎有特殊的Unicode字符和代码页895的适当承认是工作,你正在尝试的工作。这不使用微软的VFP OLEDB提供程序。不过,我的4个部分。




  1. 创建具有明确的代码页参考这通常会导致VFP可读格式的表格。


  2. 要保留你提到你的dBASE需要向后兼容性,使用COPY TO命令将VFP版本表头转换成公认的较旧的(应该是)的dBASE格式为:


  3. 简单的插入到表的的dBASE版本(也代码页895)


  4. 检索所有记录并期待在Unicode的结果。





  //连接到你的数据路径,但在连接字符串
字符串的connectionString = @供应商= VFPOLEDB.1明确引用的代码页895;数据源= C:\\YourDataPath\\SomeSubFolder ; CODEPAGE = 895;;
串ANS =;

使用(OleDbConnection的连接=新的OleDbConnection(的connectionString))
{
//创建一个免费的表(不是一个数据库的一部分)是代码页895. $表语法b $ b串CMD =创建表MyTest1免费代码页= 895(oneColumn C(10));
OleDbCommand的命令=新的OleDbCommand(CMD,连接);

connection.Open();
command.ExecuteNonQuery();

//现在,创建一个脚本,以使用MyTest1表并创建MyTest2其中
//以dBASE格式应该得到承认。
串vfpScript = @使用MyTest1
复制到MyTest2类型FOXPLUS;


command.CommandType = CommandType.StoredProcedure;
command.CommandText =EXECSCRIPT;
command.Parameters.Add(myScript的OleDbType.Char).value的= vfpScript;
command.ExecuteNonQuery();

//简单的插入到表
命令的第二个实例=新的OleDbCommand(插入Mytest2(oneColumn)值()?,连接);
command.Parameters.AddWithValue(parmForColumn,çšjír_Þ‰);
command.ExecuteNonQuery();

//现在,取回数据。
命令=新的OleDbCommand(选择Mytest2 *,连接);
OleDbDataAdapter的DA =新OleDbDataAdapter的(命令);
的DataTable oTbl =新的DataTable();
da.Fill(oTbl);

如果(oTbl.Rows.Count!= 0)
//我们应该有一个行,所以您可以通过列
//字符串,它应该LOO像Unicode的样品我上面插入。
ANS =(字符串)oTbl.Rows [0] [oneColumn];
}




显然,你通过所有的代码可循环列并设置适用的参数,所以我离开这个给你。


My goal

I need to create a .dbf file in a specific format, specified by a client. The format being dBase III .dbf with kamenicky encoding, using Integer, Character of various lengths and Double column types.

Problem

I got pretty much everything working, with only one hurdle in the way: the darn encoding refuses to work, in spite of a specific conversion table being written which switches original chars with those compatible with kamenicky encoding. This means that the output file ends up with, for example, HEX value of FF for a char which was specified as hex value of A0 in the imported string.

If you're going to (-1) the question, I would greatly appreciate information as to why are you doing so in comments - even a "You don't understand the issue sufficiently" would be of great help as I would know where to continue my research (as in, at very basics in that case)

I have kind of, sort of solved the problem (see comments), but the solution is flawed and doesn't actually answer the given question at all.

Question

How can I persuade the Jet.OLEDB provider to not mess with the encoding?

What have I tried

  • Using foxpro provider, which actually worked fine, except for the little detail that my client's software was unable to read the resulting .dbf file.

  • Inserting the data without using OleDbParameter (so the input wouldn't get properly escaped) to no avail

  • Setting a couple of different encodings via CharacterSet = xxx and some other connection string modifications that I don't quite recall right now, every time the output of A0 resulted in FF.

  • I have found an AutoTranslate property over here, but as far as I can tell it only works for SQL connections as Jet.OLEDB keeps giving me an ISAM error.

  • I have tried toying around with globalization settings, didn't help much.

Some code

Connection string:

"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0};Extended Properties=\"dBase III;\"";

Then data gets inserted using OleDbCommand, with the individual cells being filled with OleDbParameter class and constructed insert string. Might be quite useless, but here's the code:

private void insertRows(T[] data, OleDbConnection connection)
{
    using (OleDbCommand command = connection.CreateCommand())
    {
        for (int i = 0; i < data.Count(); i++)
        {
            constructParams(data[i], i, command);
            command.CommandText = constructInsert(i, _fileName);

            command.ExecuteNonQuery();
        }
    }
}

private void constructParams(T data, int index, OleDbCommand command)
{
    command.Parameters.Clear();
    foreach (PropertyInfo prop in _props)
    {
        if(_cols.ContainsKey(prop.Name))
        {
            command.Parameters.Add(new OleDbParameter("@" + prop.Name + index, prop.GetValue(data)));
        }
    }
}

private string constructInsert(int dataNum, string tableName)
{
    string insert = "INSERT INTO [" + tableName + "] (";
    foreach(string key in _cols.Keys)
    {
        insert += "[" + key + "],";
    }
    insert = insert.Remove(insert.Length - 1);
    insert += ") VALUES";

    insert += " (";
    foreach (string key in _cols.Keys)
    {
        insert += "@" + key + dataNum + ",";
    }

    insert = insert.Remove(insert.Length - 1);
    insert += ");";

    return insert;
}

解决方案

Here is a quick something I tried and appears to be working with special Unicode characters and proper recognition of codepage 895 as you are trying to work with. This does use the VFP OleDb provider from Microsoft. However, I have as 4 parts.

  1. Create the table with explicit codepage reference which typically results in VFP readable format.

  2. To retain backward compatibility as you mentioned you needed in dBASE, use the COPY TO command to convert the VFP version table header to the older (and should be) dBASE recognized format

  3. Simple insert into the dBASE version of the table (also codepage 895)

  4. Retrieve all records and look at the Unicode results.

// Connection to your data path, but explicitly referencing codepage 895 in connection string
string connectionString = @"Provider=VFPOLEDB.1;Data Source=c:\\YourDataPath\\SomeSubFolder;CODEPAGE=895;";
string ans = "";

using (OleDbConnection connection = new OleDbConnection(connectionString))
{
   // create table syntax for a free table (not part of a database) that is codepage 895.
   string cmd = "create table MyTest1 free codepage=895 ( oneColumn c(10) )";
   OleDbCommand command = new OleDbCommand(cmd, connection);

   connection.Open();
   command.ExecuteNonQuery();

   // Now, create a script to use the MyTest1 table and create MyTest2 which 
   // SHOULD BE recognized in dBASE format.
   string vfpScript = @"use MyTest1
            Copy to MyTest2 type foxplus";


   command.CommandType = CommandType.StoredProcedure;
   command.CommandText = "ExecScript";
   command.Parameters.Add("myScript", OleDbType.Char).Value = vfpScript;
   command.ExecuteNonQuery();

   // Simple insert into the 2nd instance of the table    
   command = new OleDbCommand("insert into Mytest2 ( oneColumn ) values ( ? )", connection);
   command.Parameters.AddWithValue("parmForColumn", "çšjír_Þ‰");
   command.ExecuteNonQuery();

   // Now, get the data back.
   command = new OleDbCommand("select * from Mytest2", connection);
   OleDbDataAdapter da = new OleDbDataAdapter(command);
   DataTable oTbl = new DataTable();
   da.Fill(oTbl);

   if (oTbl.Rows.Count != 0)
      // we should have one row, so get the string from the column
      // and it SHOULD loo like the Unicode sample I inserted above.
      ans = (string)oTbl.Rows[0]["oneColumn"];
}

Obviously you have code to cycle through all columns and set applicable parameters, so I leave that up to you.

这篇关于OLEDB自定义编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆