AFAIK does this works for all. Be aware that by instance in OleDB the names
are not important, however. In OleDB you have to be very much attent that
yuo fill the parameters in the sequence as in the string.
I hope this was your question,
Cor
HTH,
Bill
>
> --
> thanks - dave
> david_at_windward_dot_net
> http://www.windwardreports.com
>
That is what I was afraid of - remember @ being a problem in Oracle too. Is
there a way to make this truly portable (short of using Hibernate)? Or do I
have to have some client specific code here?
--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com
Depends on what you consider to be an SQL database. For instance,
programming an OleBbCommand against an MS Access store fails since MS Access
cannot handle named parameters.
Best regards,
Paul Gielens
Visit my blog @ http://weblogs.asp.net/pgielens/
###
You could use the Enterprise Library, which abstracts a lot of the code
between SQL Server and Oracle, including the different parameter needs
between the two. If you need an ORM, then EasyObjects will work on top of
the EntLib and supports both databases.
Enterprise Library
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/entlib.asp
EasyObjects.NET
http://www.easyobjects.net
--
Matt
"David Thielen" <thi...@nospam.nospam> wrote in message
news:7297BAC6-04F3-41A0...@microsoft.com...
That's not entirely true...
The documentation for the OleDb adapter states that you should pass a '?'
for the parameter placeholder:
SELECT * FROM Employees WHERE EmployeeID = ?
but it will accept this as well:
SELECT * FROM Employees WHERE EmployeeID = @EmployeeID
However, just because you used a named parameter, doesn't mean there is an
association between that and the OleDbParameter with the same name. For the
OleDbParameter, you *must* add them to the OleDbCommand in the same order as
they are in the SQL statement, otherwise you will get some very strange
errors.
--
Matthew Noonan
EasyObjects.NET: The O/RM for the Enterprise Library
http://www.easyobjects.net
"Paul Gielens" <pgie...@gmail.com.nospam> wrote in message
news:eFndKuhR...@TK2MSFTNGP09.phx.gbl...
This looks like it would do it EXCEPT the connection string is stored in
it's config file and I think it can't be encrypted.
--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com
http://msdn.microsoft.com/msdnmag/issues/05/07/DataPoints/
--
Matthew Noonan
EasyObjects.NET: The O/RM for the Enterprise Library
http://www.easyobjects.net
"David Thielen" <thi...@nospam.nospam> wrote in message
news:0ACEC3F7-053C-440B...@microsoft.com...
The crux of my original post is that this is a particular pernicious problem
precisely b/c it *will* work with OleDb but it *won't* work as you'd expect
it to. Because it uses the index as opposed to the name, it will make a
substitution for you. But if you added your parameters in a different order
than they appear in the query, they behave based on the order they were
entered. Worse, if you have @BillRyan as a parameter used three times, then
even if you add a param named @BillRyan, the query will blow up. Anyone
that isn't well versed in the mechanics of it will waste a good while trying
to figure out why before realizing what the problem is. Since it doesn't
blow up, it's probably the most dangerous type of problem b/c it may yeild
correct results sometimes, wrong ones others, and throw exceptions in
others. Yet the code appears to be fine. This will confuse people at best
and cause huge problems at worst. Imagine that a new developer sees the
named params and thinks that's how it works, after all it works that way
with Sql Server. Then moves the params around. It might be in production
before anyone figures out that something 'bad' just happened.
"Paul Gielens" <pgie...@gmail.com.nospam> wrote in message
news:eFndKuhR...@TK2MSFTNGP09.phx.gbl...
>
// -- CUT HERE --
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DbProviderFactory fact;
DbConnection cnn;
// Test using SqlClient
fact = DbProviderFactories.GetFactory("System.Data.SqlClient");
cnn = fact.CreateConnection();
cnn.ConnectionString = "Data Source=(local);Initial
Catalog=master;Integrated Security=True";
cnn.Open();
Test(fact, cnn);
// Test using Access
fact = DbProviderFactories.GetFactory("System.Data.OleDb");
cnn = fact.CreateConnection();
cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=c:\\db1.mdb";
cnn.Open();
Test(fact, cnn);
}
static void Test(DbProviderFactory factory, DbConnection connection)
{
ParamBuilder builder;
DbParameter param;
string marker;
builder = new ParamBuilder(factory, connection);
param = builder.CreateParameter("param1", out marker);
Console.WriteLine(String.Format("Name: {0}, SQL statement placeholder:
{1}", param.ParameterName, marker));
}
}
class ParamBuilder
{
private DbProviderFactory _factory;
private DbCommandBuilder _builder;
private string _parameterMarkerFormat;
public ParamBuilder(DbProviderFactory factory)
: this(factory, null)
{
}
public ParamBuilder(DbProviderFactory factory, DbConnection source)
{
_factory = factory;
_builder = _factory.CreateCommandBuilder();
if (source != null)
{
using (DataTable tbl =
source.GetSchema(DbMetaDataCollectionNames.DataSourceInformation))
{
_parameterMarkerFormat =
tbl.Rows[0][DbMetaDataColumnNames.ParameterMarkerFormat] as string;
}
}
if (String.IsNullOrEmpty(_parameterMarkerFormat))
_parameterMarkerFormat = "{0}";
}
public DbParameter CreateParameter(string parameterName, out string
parameterMarker)
{
DbParameter param = _factory.CreateParameter();
param.ParameterName =
(string)typeof(DbCommandBuilder).InvokeMember("GetParameterName",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.InvokeMethod |
System.Reflection.BindingFlags.NonPublic, null, _builder, new object[] {
parameterName });
parameterMarker =
String.Format(System.Globalization.CultureInfo.InvariantCulture,
_parameterMarkerFormat, param.ParameterName);
return param;
}
}
}
// -- CUT HERE --
The console output:
Name: @param1, SQL statement placeholder: @param1
Name: param1, SQL statement placeholder: ?
So to adapt the code, throw the ParamBuilder class into your project, feed
it a DbProviderFactory and an open DbConnection, then call CreateParameter()
as many times as you need to during your SQL code generation process. It'll
format the parameters and provide you with the marker string to insert into
the SQL statement to represent the parameter.
You'll probably have to make some minor tweaks to determine whether or not
the provider supports named parameters. To do that, you'll have to examine
the DataSourceInformation metadata (I get it in the constructor for the
ParamBuilder class). I *think* the ParameterMarkerPattern is null or empty
if the provider doesn't support named parameters. Either that, or the
ParameterMarkerFormat does not contain "{0}"
Robert
--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com