web-dev-qa-db-fra.com

System.ArgumentException: le paramètre de type de table doit avoir un nom de type valide

J'essaie de passer un type de table défini par l'utilisateur dans une requête en C #.

le type est défini avec 2 colonnes (org et sub org)

voici à quoi ressemble mon code:

DataSet ds = new DataSet();
try
{

    DataTable FilteredOrgSubOrg = new DataTable("OrgSubOrgValueType");
    FilteredOrgSubOrg.Columns.Add("org", typeof(string));
    FilteredOrgSubOrg.Columns.Add("subOrg", typeof(string));
    FilteredOrgSubOrg.Rows.Add(org, orgsub);
    using (SqlConnection conn = new SqlConnection(cCon.getConn()))
    {
        using (SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = 
                "select * from myTable ex where year = @year' and qtr = @qtr" +
                " and EXISTS(SELECT 1 FROM @OrgSubOrg tt  WHERE ex.org like tt.org" +
                " AND ex.orgsub = tt.suborg  )"+
                " order by ex.org,year, qtr DESC";
            // 2. set the command object so it knows
            // to execute a stored procedure

            // 3. add parameter to command, which
            // will be passed to the stored procedure
            cmd.Parameters.Add(new SqlParameter("@OrgSubOrg", FilteredOrgSubOrg));
            cmd.Parameters.Add(new SqlParameter("@year", year));
            cmd.Parameters.Add(new SqlParameter("@qtr", qtr));


            conn.Open();
            SqlDataAdapter sqlDA = new SqlDataAdapter();

            sqlDA.SelectCommand = cmd;
            sqlDA.Fill(ds);

        }
    }

est-ce que je passe les paramètres de manière incorrecte?

quand je le fais dans SQL Server comme ceci:

declare @OrgSubOrg OrgSubOrgValueType
insert into @OrgSubOrg  values ('05%','00000000')
insert into @OrgSubOrg values ('03%','00000000')


------------ complete -----------------------------------
select * from myTable ex
where 
year = '2013' and qtr = '1' 
and EXISTS(
               SELECT 1 
               FROM @OrgSubOrg tt               
               WHERE ex.org like tt.org
                 AND ex.orgsub = tt.suborg  )
order by ex.org,year, qtr DESC

everything works like it should.

j'ai aussi essayé de le passer comme ceci:

  SqlParameter p = cmd.Parameters.Add(new SqlParameter("@OrgSubOrg", SqlDbType.Structured));
                     p.Value = FilteredOrgSubOrg;

mais je reçois la même erreur

The table type parameter '@OrgSubOrg' must have a valid type name.

se pourrait-il que je ne puisse pas le passer à une commande SQL, j'ai un code similaire dans un autre endroit, qui fonctionne très bien avec une procédure stockée ...?

31
Madam Zu Zu

Définissez le mappage sur votre type dans SqlServer à l'aide de la propriété TypeName qui: obtient ou définit le nom du type pour un paramètre de valeur de table, qui doit être corrigé.

p.TypeName = "dbo.MyType";

Vérifiez également Paramètres table post

64
volody

Notez que cela peut également se produire lorsque vous exécutez une procédure stockée et que SqlCommand.CommandType n'est pas défini sur CommandType.StoredProcedure, en tant que tel:

using (SqlCommand cmd = new SqlCommand("StoredProcName", conn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.ExecuteNonQuery();
}
6
bvoyelr

Vous pouvez également obtenir cette erreur lorsque vous souhaitez passer des paramètres de table dans une procédure stockée. Cela se produit si vous utilisez l'entité famework Context.Database.SqlQuery (). Vous devez obligatoirement définir la propriété TypeName pour vos paramètres de table.

SqlParameter codesParam = new SqlParameter(CODES_PARAM, SqlDbType.Structured);
            SqlParameter factoriesParam = new SqlParameter(FACTORIES_PARAM, SqlDbType.Structured);

            codesParam.Value = tbCodes;
            codesParam.TypeName = "[dbo].[MES_CodesType]";
            factoriesParam.Value = tbfactories;
            factoriesParam.TypeName = "[dbo].[MES_FactoriesType]";


            var list = _context.Database.SqlQuery<MESGoodsRemain>($"{SP_NAME} {CODES_PARAM}, {FACTORIES_PARAM}"
                , new SqlParameter[] {
                   codesParam,
                   factoriesParam
                }
                ).ToList();
4
trueboroda