2009-08-19 8 views
4

J'essaie d'utiliser Npgsql pour appeler une fonction (procédure stockée) qui prend un paramètre CHARACTER comme paramètre, mais cela ne fonctionne pas. Si je déclare la même fonction sans paramètre, ou avec un paramètre INTEGER, j'obtiens les ensembles de résultats que je veux. Lorsque je déclare le paramètre en tant que caractère, il cesse de fonctionner. Qu'est-ce qui ne va pas?Utilisation de npgsql pour appeler une fonction qui prend le caractère comme paramètre

Voici le code de ma fonction:

CREATE OR REPLACE FUNCTION testrefcursor1(in xxx character varying(10)) RETURNS SETOF refcursor AS 
$$ 
DECLARE 
    ref1 refcursor; 
    ref2 refcursor; 
BEGIN 

OPEN ref1 FOR 
SELECT * FROM accounts; 
RETURN NEXT ref1; 

OPEN ref2 FOR 
SELECT * FROM accounts; 
RETURN NEXT ref2; 

RETURN; 
END; 
$$ 
LANGUAGE plpgsql; 

Et voici le code C# que j'utilise:

var connection = new Npgsql.NpgsqlConnection(connectionString.ConnectionString); 

connection.Open(); 
var trans = connection.BeginTransaction(); 

var command = new Npgsql.NpgsqlCommand("testrefcursor1", connection); 
command.CommandType = System.Data.CommandType.StoredProcedure; 

var parameter = command.CreateParameter(); 
parameter.ParameterName = "xxx"; 
parameter.DbType = System.Data.DbType.String; 
parameter.Value = "10"; 
command.Parameters.Add(parameter); 

var da = new Npgsql.NpgsqlDataAdapter(command); 
var ds = new System.Data.DataSet(); 
da.Fill(ds); 

trans.Commit(); 
connection.Close(); 

J'ai déjà essayé de déclarer le paramètre que le caractère, CARACTERE (10) , CHARACTER VARYING et CARACTER VARYING (10) ...

EDIT: Je n'obtiens aucun message d'erreur, mais au lieu d'obtenir le jeu de résultats attendu, j'obtiens un jeu de résultats vide avec une seule colonne comme le nom de la fonction que j'essaie d'appeler.

+7

... Qu'est-ce qui ne va pas avec Postgres? – Eric

Répondre

5

Vous passez un argument Unicode à un paramètre ASCII.

Modifier cette ligne:

parameter.DbType = System.Data.DbType.String; 

Pour:

parameter.DbType = System.Data.DbType.AnsiString; 

En général, varchar colonnes de Postgres sont en Unicode, à condition que l'option Unicode sur la base de données est activée (see here). Je suppose que ce n'est pas le cas, et que votre paramètre est incapable de se convertir dans le bon type à passer par la fonction.

+0

J'ai essayé avec DbType.String, DbType.AnsiString, DbType.StringFixedLength et DbType.AnsiStringFixedLength, à la fois avec et sans spécifier une longueur de paramètre et aucun travaillé :( –

+0

Quel est le message d'erreur que vous obtenez? – Eric

+0

Je ne reçois aucun message d'erreur , mais au lieu d'obtenir le jeu de résultats attendu, j'obtiens un jeu de résultats vide avec une seule colonne qui a le même nom que la fonction que j'essaie d'appeler –

1

Je ne suis pas sûr, si cela a à voir avec votre problème, mais hier je suis tombé sur le fact que PostgreSQL a un caractère de "type interne à octet unique" qui est différent du type char (1). Peut-être qu'il y a une certaine confusion à ce sujet?

+0

Je ne pense pas que j'utilise ce type de données. . –

+0

Avez-vous adapté votre création de commande à * var commande = new Npgsql.NpgsqlCommand ("testrefcursor1 (: xxx)", connexion); * lorsque vous avez utilisé une liste de paramètres non vide? – Whoever

+0

Selon la documentation, je devrais spécifier uniquement le nom de la fonction: "Si vous avez des paramètres dans votre fonction, affectez uniquement le nom de la fonction à la propriété CommandText et ajoutez des paramètres à la collection NpgsqlCommand.Parameters comme d'habitude. prenez soin de lier correctement vos paramètres. " http://npgsql.projects.postgresql.org/docs/manual/UserManual.html –

2

Quelle version de Npgsql utilisez-vous?

De plus, pouvez-vous spécifier le type de paramètre en utilisant NpgsqlDbType? Parfois, le mappage n'est pas exactement et Npgsql ne trouve pas la fonction que vous essayez d'utiliser et ne peut pas le faire fonctionner. Npgsql essaie de trouver une correspondance exacte du nom de la fonction et des types de paramètres.

DbString correspond aux types de paramètres de texte. Pourriez-vous essayer et changer votre type de paramètre en texte?

J'espère que ça aide.

+0

Merci pour votre réponse. Je ne travaille plus sur ce projet, mais je vais essayer de trouver le temps de l'essayer. Je posterai mes résultats ici. –

0

J'ai essayé avec l'approche ci-dessous (qui est similaire à la vôtre):

using (NpgsqlConnection connection = new NpgsqlConnection(<connectionString>)) 
{ 
    DataSet ds = new DataSet(); 
    DataTable dt = new DataTable(); 
    connection.Open(); 
    NpgsqlCommand cmd = new NpgsqlCommand(< name of your SP >, connection); 
    cmd.CommandType = CommandType.StoredProcedure; 
    var param = cmd.CreateParameter(); 
    param.ParameterName = < exact parameterName you used in your SP>; 
    param.DbType = System.Data.DbType.AnsiString; 
    param.Value = < parameter value >; 
    cmd.Parameters.Add(param); 
    NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(cmd); 
    adapter.Fill(ds); 
    dt = ds.Tables[0]; 
} 

Cela fonctionne bien pour moi et je suis en train de DataTable bon.