我正在Windows环境和Visual Studio 2017中使用C#和SQL Server。我试图将数据表(称为@profiles
)传递给SQL脚本。
为此,我首先必须创建一个与传递的数据表匹配的表类型。
问题是,我尝试通过传递的数据表填充新表的所有方式,都是两种异常之一:
“列,参数或变量@profiles 。:找不到数据类型ProfileIdTableType。”
“表类型参数'@profiles'必须具有有效的类型名称。”
从我的搜索中,我发现过程通常使用具有新表类型的数据表,但是无论如何-我仍然会遇到上述异常。
我试图声明一个新的表类型,并将@profiles
与它一起使用没有成功。
当我声明要使用的SqlParameter
时,通常会遇到第一个异常(找不到类型)
我应该提到,我无法在SQL Server的“可编程性”部分中找到创建的类型(但是我的类型是temp,所以应该是)
这是我用来将数据表从C#传递到脚本的两种方式:
SqlParameter @profiles = new SqlParameter("@profiles", profileIds.Tables[0]);
profiles.TypeName = "ProfileIdTableType";
或:
DbParameter @profiles = new SqlParameter("@profiles", profileIds.Tables[0]);
然后使用它:
updatedProfiles = (int)DbAdminOps.ExecuteNonQueryCommand(updateProfileSettingsCommand, CommandType.Text, new DbParameter[] { @profiles, @updatedTemplate }, null);
这是我上次使用的SQL脚本(但尝试了许多此处未介绍的变体)
-- create a table type of profile Ids passed by user
CREATE TYPE ProfileIdTableType AS TABLE (ID INT)
go
DECLARE @PRFL ProfileIdTableType
GO
CREATE PROCEDURE PopulateTable
@profiles ProfileIdTableType READONLY
AS
INSERT INTO @PRFL(ID)
SELECT [ID] FROM @profiles
GO
@profiles ProfileIdTableType
EXEC PopulateTable @profiles
go
我希望@profiles被识别为表格,因此我可以在脚本中使用它,但我得到的实际上只是异常。我付出了很多努力,但没有做到。
遍历所有堆栈溢出问题,youtube,microsoft文档和网络。
如果有什么我遗漏的重要信息-让我知道。
真的很感谢一些建议。
干杯!
答案 0 :(得分:0)
关键点是将SqlDbType指定为“结构化”,然后定义TypeName,如以下代码片段所示。
comm.Parameters.AddWithValue("@tvpEmails", dt);
// EMAIL.TVP_Emails should exist on your SQL instance under UDDT types
comm.Parameters[comm.Parameters.Count - 1].TypeName = "EMAIL.TVP_Emails";
comm.Parameters[comm.Parameters.Count - 1].SqlDbType = SqlDbType.Structured;
请参阅下面的完整代码。如果您有任何困难,请告诉我。
using System.Data;
using System.Data.SqlClient;
using System.Net.Mail;
namespace ConsoleApp10
{
class Program
{
static void Main(string[] args)
{
var mm = new MailMessage();
using (var conn = new SqlConnection("your connection string"))
{
using (var comm = new SqlCommand())
{
comm.Connection = conn;
conn.Open();
comm.CommandText =
@"INSERT INTO [EMail].[MailAttachments] (fileName,fileSize,attachment)
SELECT fileName, fileSize, attachment FROM @tvpEmails";
var dt = CreateTable();
foreach (var eml in mm.Attachments)
{
var newRow = dt.NewRow();
newRow["FileName"] = eml.Name;
newRow["FileSize"] = eml.ContentStream.Length;
var allBytes = new byte[eml.ContentStream.Length];
newRow["Attachment"] = allBytes;
eml.ContentStream.Position = 0;
dt.Rows.Add(newRow);
}
comm.Parameters.AddWithValue("@tvpEmails", dt);
comm.Parameters[comm.Parameters.Count - 1].TypeName = "EMAIL.TVP_Emails";
comm.Parameters[comm.Parameters.Count - 1].SqlDbType = SqlDbType.Structured;
comm.ExecuteNonQuery();
if (conn.State == ConnectionState.Open)
conn.Close();
}
}
}
private static DataTable CreateTable()
{
var dt = new DataTable();
dt.Columns.Add("FileName", typeof(string));
dt.Columns.Add("FileSize", typeof(long));
dt.Columns.Add("Attachment", typeof(byte[]));
return dt;
}
}
}