[Mono-list] Parameters & SQLite
Jay R. Wren
jrwren at xmtp.net
Thu Aug 31 12:41:03 EDT 2006
Adam Tauno Williams wrote:
>> It is my blog, but take a look anyway.
>> http://little.xmtp.net/blog/2005/10/21/proper-data-abstraction-in-net-and-mono-applications/
>> http://little.xmtp.net/blog/2005/11/22/more-proper-data-abstractions-in-net-and-mono-applications/
>> The short answer is "yes" parameters are supported. There are examples
>> at the above URLs.
>> A short example:
>> |IDbCommand idcSelect = conn.CreateCommand();
>> idcSelect.CommandText = "select col from table where othercl=@someting";
>> ||IDataParameter param = idcSelect.CreateParameter();
>> Cmd.Parameters.Add(param);
>> param.ParameterName = "@someting";
>> param.DbType = DbType.String;
>> param.Value = "whatever something would equal";
>> The above is more geared to 1.1, since 2.0 has DbConnection and the
>> ADO2.0 db provider stuff.
>>
>
> Excellent!
>
> I'm trying to create a routine that automatically stores a Hashtable (a
> result from an expensive RPC) into a database as a cache. Each key in
> the Hashtable corresponds to a column in the table, which the key
> entityName containing the name of the table. The routine compiles fine
> but then just hangs when ExecuteNonQuery is called.
>
> ------
> IDbCommand command = connection.CreateCommand();
> int count = 0;
> string columnList = "";
> string valueList = "";
> foreach(string key in dictionary.Keys)
> {
> IDataParameter parameter;
> if (count > 0)
> {
> columnList = columnList + ", ";
> valueList = valueList + ", ";
> }
> columnList = columnList + key;
> valueList = valueList + "@" + key;
> parameter = command.CreateParameter();
> command.Parameters.Add(parameter);
> if (dictionary[key].GetType().FullName == "System.String")
> {
> parameter.ParameterName = "@" + key;
> parameter.DbType = DbType.String;
> parameter.Value = (string)dictionary[key];
> } else if (dictionary[key].GetType().FullName == "System.Int32")
> {
> parameter.ParameterName = "@" + key;
> parameter.DbType = DbType.Int32;
> parameter.Value = (int)dictionary[key];
> } else if (dictionary[key].GetType().FullName == "System.DateTime")
> {
> parameter.ParameterName = "@" + key;
> parameter.DbType = DbType.DateTime;
> parameter.Value = (DateTime)dictionary[key];
> } else throw new System.Exception("Unhandled type in response");
> count++;
> }
> command.CommandText =
> "INSERT INTO " + (string)dictionary["entityName"] +
> " (" + columnList + ") VALUES (" + valueList + ");";
> Console.WriteLine("Dictionary.StoreHash: Executing non-query");
> command.ExecuteNonQuery();
> Console.WriteLine("Dictionary.StoreHash: Non-query complete");
> command.Dispose();
>
I could not duplicate the error, but I was able to get something which
does this working. What fixed it for me was to move the
command.Parameters.Add(parameter) to after the parameter object was int
the desired state. I don't know if Parameter objects are immutable, or
if command.Parameters.Add() makes a copy of the paremeter, or what, but
this fixed it for me. It may be worth comparing this behavior to the MS
platform and see what happens.
And of course I used command line sqlite3 to create the table, and after
execution did a .dump to verify it worked. It did.
My connection string in the ProviderFactory string:
<add key="test"
value="factory=Mono.Data.SqliteClient;URI=file:sqlitetest.db,version=3" />
My (only slightly modified) code:
/* CREATE TABLE testtable ( int1 int, str1 nvarchar(1000), entityName
nvarchar(1000) );
*/
using System;
using System.Data;
using System.Collections;
using Mono.Data;
class MonoSqlLiteTest
{
public static void Main(string[] args)
{
Hashtable dictionary = new Hashtable();
dictionary.Add("str1","blah");
dictionary.Add("entityName","testtable");
dictionary.Add("int1",2);
IDbConnection connection =
ProviderFactory.CreateConnectionFromConfig("test");
IDbCommand command = connection.CreateCommand();
int count = 0;
string columnList = "";
string valueList = "";
foreach(string key in dictionary.Keys)
{
IDataParameter parameter;
if (count > 0)
{
columnList = columnList + ", ";
valueList = valueList + ", ";
}
columnList = columnList + key;
valueList = valueList + "@" + key;
parameter = command.CreateParameter();
if (dictionary[key].GetType().FullName == "System.String")
{
parameter.ParameterName = "@" + key;
parameter.DbType = DbType.String;
parameter.Value = (string)dictionary[key];
Console.WriteLine("string parameter
added:"+key+" "+dictionary[key]);
} else if (dictionary[key].GetType().FullName ==
"System.Int32")
{
parameter.ParameterName = "@" + key;
parameter.DbType = DbType.Int32;
parameter.Value = (int)dictionary[key];
Console.WriteLine("int parameter added:"+key+"
"+dictionary[key]);
} else if (dictionary[key].GetType().FullName ==
"System.DateTime")
{
parameter.ParameterName = "@" + key;
parameter.DbType = DbType.DateTime;
parameter.Value = (DateTime)dictionary[key];
Console.WriteLine("datetime parameter
added:"+key+" "+dictionary[key]);
} else
throw new System.Exception("Unhandled type in
response");
command.Parameters.Add(parameter);
count++;
}
command.CommandText =
"INSERT INTO " + (string)dictionary["entityName"] +
" (" + columnList + ") VALUES (" + valueList + ")";
Console.WriteLine("Dictionary.StoreHash: Executing
non-query:" + command.CommandText);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
Console.WriteLine("Dictionary.StoreHash: Non-query
complete");
command.Dispose();
}
}
--
Jay
More information about the Mono-list
mailing list