我们一直在使用用户定义的表类型将整数列表传递给我们的存储过程.
然后我们使用它们连接到存储过程查询中的其他表.
例如:
CREATE PROCEDURE [dbo].[sp_Name]
(
@Ids [dbo].[OurTableType] READONLY
)
AS
SET Nocount ON
SELECT
*
FROM
SOMETABLE
INNER JOIN @Ids [OurTableType] ON [OurTableType].Id = SOMETABLE.Id
Run Code Online (Sandbox Code Playgroud)
在使用更大的数据集时,我们发现这方面的表现很差.
我们用来加快速度的一种方法是将内容转储到临时表中,然后将其加入.
例如:
CREATE PROCEDURE [dbo].[sp_Name]
(
@Ids [dbo].[OurTableType] READONLY
)
AS
SET Nocount ON
CREATE TABLE #TempTable(Id INT)
INSERT INTO #TempTable
SELECT Id from @Ids
SELECT
*
FROM
SOMETABLE
INNER JOIN #TempTable ON #TempTable.Id = SOMETABLE.Id
DROP TABLE #TempTable
Run Code Online (Sandbox Code Playgroud)
这确实显着提高了性能,但我希望对这种方法以及我们未考虑的任何其他后果有所了解.关于为什么这改善性能的解释也可能是有用的.
NB有时我们可能需要传递的不仅仅是一个整数,因此我们不使用逗号分隔列表或类似的东西.
t-sql sql-server user-defined-types table-valued-parameters sql-server-2008-r2
我想将一个表值参数作为变量传递给存储过程,并且在类SqlMetadata1 的构造函数中,可以指定要在表的列中添加的字符串的长度(long maxLength).
Microsoft.SqlServer.Server.SqlMetaData[] tvpdefinition =
{
new SqlMetaData("ValueOne", SqlDbType.NVarChar, 100),
new SqlMetaData("ValueTwo",SqlDbType.NVarChar, 100)
}
Run Code Online (Sandbox Code Playgroud)
如何指定'max'长度以使其与此列对应
ValueOne (nvarchar(max), not null)
Run Code Online (Sandbox Code Playgroud)
例如,与长度值100相反
我正在尝试从EntityFramework调用一个使用Table-value参数的存储过程.
但是当我尝试进行功能导入时,我不断收到一条警告信息 -
函数"InsertPerson"在参数索引0处具有参数"InsertPerson_TVP",其具有数据类型"表类型",目前.NET Framework版本当前不支持该类型.该功能被排除在外.
我在这里进行了一次初步搜索,发现很少有帖子说在EntityFrameWork中有可能有一些解决方法,很少有人说它在当前版本中不受支持.
对于这个问题,有没有人知道更好的方法或解决方案?
stored-procedures entity-framework bulkinsert table-valued-parameters
我正在使用SQL Server 2008.
如何将Table Valued参数传递到跨不同数据库的存储过程,但是相同的服务器?
我应该在两个数据库中创建相同的表类型吗?
请根据问题给出一个示例或链接.
谢谢你的帮助.
我在 SQL Server 中有一个用户定义的函数,它接受 TVP(表值参数)作为参数。在 EF 中,如何从 C# 调用这样的函数?
我尝试使用该方法,ObjectContext.CreateQuery<>但出现以下错误:
函数“QueryByParam”的参数“param”无效。参数只能是可以转换为 Edm 标量类型的类型。
也尝试过方法ObjectContext.ExecuteStoreQuery<>并得到相同的错误。IQueryable无论如何它都不会返回。
示例代码
[DbFunction(nameof(SampleDbContext), "QueryByParam")]
public IQueryable<SecurityQueryRow> QueryByParam(IEnumerable<ProfileType> profiles, bool isActive = false)
{
DataTable dataTable = ....
ObjectParameter profilesParam = new ObjectParameter("profileTypeIds", dataTable);
ObjectParameter isActiveParam = new ObjectParameter("isActive ", isActive);
return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<SecurityQueryRow>(
string.Format("[{0}].[{1}](@profileTypeIds, @isActive)", GetType().Name, "QueryByParam"),
profilesParam,
isActiveParam);
}
Run Code Online (Sandbox Code Playgroud)
要求是我们需要一个 IQueryable 返回,而不是消耗的结果。
c# sql-server entity-framework table-valued-parameters entity-framework-6
在代码隐藏中,您将TVP添加为存储过程的SqlDbType.Structured但这在ASP.NET SqlDataSource控件中不存在.
我已将我的Datatables存储在会话变量中(不要担心它们很小!)我需要将它们作为参数传递给SqlDataSource(它有许多数据绑定对象)
我将Datasource指向了session变量,但在转换为表类型时失败了.
编辑:假设我将Session变量从等式中取出(因为,实际上,它完全相切)
必须有一种方法可以将DBType.Structured附加到SQLDataSource.我的列表视图是适当的数据绑定,但它们附加的商店程序必须采用TVP
我无法相信没有办法为SQLDataSource发送TVP参数?我有什么选择?
EDIT2:我一直在寻找为SqlDataSource创建一个自定义参数,但在我看来,它的"eval"方法对结构化数据类型不满意
EDIT3:我的唯一选择就是为我的数据绑定控件完成代码隐藏的所有工作.我添加了赏金以防其他任何人有一个优雅的解决方案.
编辑方式4:或许,有一种方法可以将表作为对象传递给存储过程,然后让SQL Server将其转换为TVP吗?
我有一个像这样的SQL CLR函数:
public partial class UserDefinedFunctions {
[Microsoft.SqlServer.Server.SqlFunction(TableDefinition = "number int", FillRowMethodName = "FillRow")]
public static IEnumerable MyClrFunction(object obj) {
// read obj array input and then
var result = new ArrayList();
result.Add((SqlInt32)1);
result.Add((SqlInt32)2);
result.Add((SqlInt32)3);
return result;
}
public static void FillRow(object obj, out SqlInt32 number) {
number = (SqlInt32)obj;
}
}
Run Code Online (Sandbox Code Playgroud)
我想用这种方式使用它:
DECLARE @x arrayOfInt
INSERT INTO @x VALUES (10)
INSERT INTO @x VALUES (20)
INSERT INTO @x VALUES (30)
SELECT * FROM dbo.MyClrFunction(@x)
Run Code Online (Sandbox Code Playgroud)
arrayOfInt是:
CREATE TYPE [dbo].[arrayOfInt] …Run Code Online (Sandbox Code Playgroud) sql-server sqlclr user-defined-functions table-valued-parameters
在实现表值参数时,生成IEnumerable<SqlDataRecord>参数使用的最常见方法之一是这样的代码(例如,https://stackoverflow.com/a/10779567/18192):
public static IEnumerable<SqlDataRecord> Rows(List<int> simpletable)
{
var smd = new []{ new SqlMetaData("id", SqlDbType.Int)};
var sqlRow = new SqlDataRecord(smd);
foreach (int i in simpletable)
{
sqlRow.SetInt32(0, i);
yield return sqlRow;
}
}
//...
var param = sqlCmd.Parameters.AddWithValue("@retailerIDs", Rows(mydata));
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "myTypeName";
Run Code Online (Sandbox Code Playgroud)
这段代码似乎确实有效.虽然重用SqlMetaData并没有引发太多的警钟,但声明SqlDataRecord外面的foreach循环让我感到非常怀疑:
修改可变对象,然后重复生成.
作为一个关于这个问题的一个例子,var x = Rows(new[] { 100, 200}.ToList()).ToList().Dump()在LinqPad中调用吐出来200,200.这种方法似乎依赖于实现细节(行是单独处理的),但我没有看到任何承诺这样做的文档.
是否有一些减轻因素使这种方法安全?
在 postgresql 中 - 什么是具有表值参数(MSSQL)的存储过程的等价物?
是否有可能,如果是这样,如何使用SQL EXEC将数据传递给存储函数的表值参数?
我知道如何从C#传递数据.使用表值参数的四个存储过程之一不会产生预期结果.我想从SQL服务器管理工作室执行我的proc以进行调试,但是如果这样的语法存在,我无法找到正确的语法.我没有在文档中找到任何相关内容.
我的类型表:
CREATE TYPE [MyNameSpace].[MyTypeTable] AS TABLE(
//... all my fields
)
Run Code Online (Sandbox Code Playgroud)
我的存储过程:
//... bunch of stuff
ALTER PROCEDURE [MyNameSpace].[MyStoredProc]
@MyTypeTableVar MyTypeTable READONLY
AS
BEGIN
//Do a bunch of stuff
//Want to test the stuff in here
END
Run Code Online (Sandbox Code Playgroud)
我试过了:
IF OBJECT_ID('tempdb.dbo.#MyTempTable') IS NOT NULL DROP TABLE tempdb.dbo.#MyTempTable;
select top 0 *
into #MyTempTable
//existing table with structure that matches the table-valued param
from MyNameSpace.MyTable;
//...Long insert statement assigning test data to #MyTempTable
EXECUTE MyNameSpace.MyStoredProc @MyTypeTableVar = #MyTempTable;
Run Code Online (Sandbox Code Playgroud)
抛出: …