【问题标题】:System.ArgumentException: The table type parameter must have a valid type nameSystem.ArgumentException:表类型参数必须具有有效的类型名称
【发布时间】:2021-09-01 19:47:34
【问题描述】:

我正在尝试将用户定义的表类型传递给 C# 中的查询。

类型定义为 2 列(org 和 sub org)

这是我的代码的样子:

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);

        }
    }

我传递的参数不正确吗?

当我在 SQL Server 中这样做时:

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.

我也试过像这样传递它:

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

但是遇到同样的错误

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

可能是我无法将它传递给 SQL 命令吗,我在另一个地方有类似的代码,它适用于存储过程...?

【问题讨论】:

    标签: c# asp.net .net sql-server-2008


    【解决方案1】:

    使用 TypeName 属性在 SqlServer 中设置映射到您的类型:获取或设置必须修复的表值参数的类型名称。

    p.TypeName = "dbo.MyType";
    

    也检查Table-Valued Parameters post

    【讨论】:

    • 不能作为嵌入在代码中的查询,一旦我用它创建了一个存储过程,我所有的问题都消失了。
    • 这正是我的问题。谢谢!
    • 我的问题或多或少也是如此。就我而言,它已经是一个存储过程,但我正在使用 QueryType.Text 执行对数据库的调用。更改为 QueryType.StoredProcedure 修复了它。
    【解决方案2】:

    请注意,当您执行存储过程并且没有将 SqlCommand.CommandType 设置为 CommandType.StoredProcedure 时,也可能会发生这种情况:

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

    【讨论】:

    • ^ 在查看 TypeName 之前我会先检查一下。似乎这更有可能是任何 vanilla SqlCommand 收到此错误的原因
    【解决方案3】:

    当您想将表参数传递给存储过程时,您也会遇到此错误。如果你使用实体名作 Context.Database.SqlQuery(),就会发生这种情况。您必须为表参数设置 TypeName 属性。

    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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 2011-09-26
      • 2023-03-24
      • 2012-04-06
      相关资源
      最近更新 更多