我使用过各种版本的MS SQL Server,包括2000,2005,2008,R2,(部分)Denali.对于像存储过程中的Table Valued参数这样的新功能,我从未如此兴奋过.我也在进行C#开发,我正在挖掘TVP,我用它来减少来自我的前端应用程序的数据库调用次数.
现在我真正的问题是使用表值参数的缺点是什么.它实在太好了.
请分享你的想法.另外,我不想太深入使用它,必须改变.
首先,我了解主键在SQL或与此相关的任何数据库中的表上的作用。
但是,当涉及到用户定义的表类型时,我发现自己无法理解为什么应该创建主键。根据我的经验,我发现它们并没有带来性能上的好处,但是我怀疑我的发现可能是由于我对它们的一般用法和有限的经验,而不是更有经验的观点。
例如,我通常将表值参数用于插入/更新过程,或传递用于创建选择查询的值数组。我发现它们没有任何性能优势,而且如果有任何表现,我会发现性能略有下降(但是我们最多只能说10毫秒,因此可以忽略不计)。
我应该透露,传递给它们的任何数据都已经非常仔细地清理/整理过,因此有可能因此而看不到收益,但是我无法轻易知道。
因此,问题又来了,我应该对用户定义的表类型使用主键,还是不那么重要?
抱歉,如果这是重复的。我进行了大量搜索,但随后可能使用了错误的关键字组合。
您的见解一如既往,将不胜感激。
使用下面的存储过程,我可以在给定每条记录的Row索引的情况下选择表的变量部分.我试图创建另一个类似于的存储过程MulTselect,只是这次表值参数将有另一列用于MulTUpdate存储过程的新值.
[RowIndex] int, [NewVal] [varchar] (4000) NOT NULL
Run Code Online (Sandbox Code Playgroud)
问题是,给定记录 - Rowindex和"NewValue",是否可以对多个记录进行UPDATE,如下面的选择程序?
--sproc signature
CREATE Proc [dbo].[MulTSELECTViaRowIndexSpTVP]
@SelectedTableName varchar (50),
@SelectedAction varchar(10),
@TestMulTSELECTViaRowIndexTVPar dbo.TestMulTSELECTViaRowIndexTVType READONLY
SET @CmdStr = 'SELECT * FROM ' + @SelectedTableName + '
WHERE RowIndex in (SELECT RowIndex from @TestMulTSELECTViaRowIndexTVPar);'
EXEC sp_executesql @CmdStr,N' @TestMulTSELECTViaRowIndexTVPar dbo.TestMulTSELECTViaRowIndexTVType READONLY',
@TestMulTSELECTViaRowIndexTVPar= @TestMulTSELECTViaRowIndexTVPar
Run Code Online (Sandbox Code Playgroud) 我有一些IN条款的SQL查询.为了改进查询计划缓存,我决定使用表值参数.这是样本WHERE ID IN (SELECT ID FROM @P1).@ P1是以下类型的变量:
CREATE TYPE [dbo].[Ids] AS TABLE(
[ID] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
Run Code Online (Sandbox Code Playgroud)
但我注意到一些查询变慢了.这是查询示例:
select * from SomeTable s where ((s.SomeForeignId in (select id from @p1)) or s.SomeForeignId is null)
Run Code Online (Sandbox Code Playgroud)
我的数据库在2.1秒内执行.
和旧查询:
select * from SomeTable s where ((s.SomeForeignId in (1,2,3.....)) or s.SomeForeignId is null)
Run Code Online (Sandbox Code Playgroud)
在1.8秒内完成.
我注意到查询计划的不同之处.第一个查询的计划由2部分组成(一个用于空检查,一个用于in子句)然后是连接.而第二个计划只是索引寻求.
有什么方法可以改进我的参数化查询以更快地执行?
PS这只是示例提取的查询,我想知道这in (select id from @p1)部分是否有任何不正确之处.
下面是插入我的数据的函数.
using (SqlCommand insSwipeDataCommand = connection.CreateCommand())
{
insSwipeDataCommand.Transaction = transaction;
insSwipeDataCommand.CommandType = CommandType.StoredProcedure;
insSwipeDataCommand.CommandText = "dbo.insSwipeData_sp";
SqlParameter attendeeTableParam = insSwipeDataCommand.Parameters.Add("@AttendeeTable", SqlDbType.Structured);
attendeeTableParam.Value = this.dataTable;
attendeeTableParam.TypeName = "AttendeeTableType";
// add orgid parameter
insSwipeDataCommand.Parameters.Add("@orgId", SqlDbType.UniqueIdentifier).Value = this.organizationId;
insSwipeDataCommand.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)
insSwipeData_sp
create PROC dbo.insSwipeData_sp
(@AttendeeTable AttendeeTableType READONLY
,@orgId UNIQUEIDENTIFIER
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @enteredUserId UNIQUEIDENTIFIER
SET @enteredUserId = 'xxxxxxxxx-xxxx-xxx-xxxx-xxxxxxxxxx'
-- Delete old Swipe records
DELETE FROM dbo.swipeData_tbl
WHERE orgId = @orgId
-- CREATE Swipe Records
INSERT INTO dbo.swipeData_tbl
(orgId, sdid, …Run Code Online (Sandbox Code Playgroud) 我相当肯定将参数嗅探添加到表值参数几乎没有价值,但是我想知道是否有人可以确认这一点?
(INT_LIST 是用户定义的表类型,它是 INT 类型的单列)
CREATE PROCEDURE [dbo].[TVPSniffTest](
@param1 varchar(50),
@idList INT_LIST readonly
)
AS
BEGIN
DECLARE @param1_sniff VARCHAR(50) = @param1 --this is worth doing
DECLARE @idList_sniff INT_LIST
INSERT INTO @idList_sniff SELECT value FROM @idList --will this help?
--query code here
END
Run Code Online (Sandbox Code Playgroud) 是否可以将类型为"[int] IDENTITY(1,1)"的列的"table"类型的参数传递给过程,并使用作为输入参数传递的DataTable对象执行此存储过程?
我收到以下错误:"INSERT到表变量上不允许的标识列.表值参数\"@ xxxxx \"的数据不符合参数的表类型."
我能找到的唯一相关注释是"如果在表值参数中为标识列提供值,则必须为会话发出SET IDENTITY_INSERT语句."
似乎即使没有在表参数中设置PK,它也会在某个时刻自动设置.这种情况发生在哪里,如何避免?
我正在开发一个从Excel到SQL Server 2008 R2执行CRUD操作的财务应用程序.该应用程序使用VBA和ADO.我试图优化循环数千行的操作的性能,并将更新发送到数据库.目前,每行调用一次存储过程.
当用户与应用程序的连接速度较慢时,性能也很慢,足以让他们开始抱怨.为了优化性能,我试过:
我的事情已经不多了.从VBA转到SQL Server 2008 R2时,如何提高数据库性能?
excel vba excel-vba table-valued-parameters sql-server-2008-r2
我希望仅通过一次存储过程调用来传递自定义对象列表。这是对象
public class OGFormResponse
{
public string Response {get; set;}
public OGFormLabelVO FormLabel {get; set;}
}
public class OGFormLabelVO
{
public int OGFormLabelKey {get; set;}
public string FormType {get; set;}
public string LabelText {get; set;}
public string ControlName {get; set;}
public string DisplayStatus {get; set;}
public string LabelType = {get; set;}
public bool IsActive {get; set;}
public string LabelParentControlName {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
这是数据库关系
CREATE TABLE [dbo].[OGFormLabels](
[OGFormLabelKey] [int] IDENTITY(1,1) NOT NULL,
[OGFLText] [nvarchar](max) NULL,
[OGFLControlName] [nvarchar](50) NOT NULL,
[OGFLIsActive] [bit] …Run Code Online (Sandbox Code Playgroud) 我有一个接受表值参数的存储过程。我想将 int 数组传递给它,但现在我收到此错误:
无法将参数值从 Object[] 转换为 IEnumerable`1。
我的代码:
int[] orderIds; //int array which contains 0 or more values
List<SqlParameter> queryList = new List<SqlParameter>
{
new SqlParameter("@companyId", SqlDbType.Int) {Value = companyId},
new SqlParameter("@marketplaceId", SqlDbType.Int) {Value = marketplaceId},
new SqlParameter("@marketlocalId", SqlDbType.Int) {Value = marketLocal},
new SqlParameter("@storeId", SqlDbType.Int) {Value = storeId}
};
if (orderIds != null)
{
queryList.Add(new SqlParameter("@OrderIdsSpecified", SqlDbType.Bit) {Value = 1});
// converting int array to object array
queryList.Add(new SqlParameter("@OrderIds", SqlDbType.Structured) {Value = orderIds.Select(orderId => (object)orderId).ToArray() });
}
using (SqlDataReader reader …Run Code Online (Sandbox Code Playgroud)