我有数百个 SP,我想知道:
当然,我可以手动浏览每一个并将其写下来,但其中的乐趣在哪里...不,从字面上看,其中的乐趣在哪里:)
这可以完成还是 Sql Management Studio 2008 R2 已经具有此功能?
我什至不知道从哪里开始,所以任何答案都是可以接受的。
编辑以增强问题:如果我们将其视为 2 个不同的任务,我们是否可以更轻松地完成此任务。甚至在客户端使用反射。(一个快速而肮脏的控制台应用程序就足够了。)
我正在尝试将自定义字符串与一个 int 变量连接起来。Investigation is pending for ['+ @investigationidout +']. 当我将鼠标指针悬停在第一个+标志上时,它说:
'+' 附近的语法不正确
这可能吗 ?
我需要看到类似的东西:
1234 的调查正在等待中
我的查询:
EXEC sp_wf_create_notification
@processid,
@vactivityid,
@vstepid,
1,
@vidColumn,
@vidColumnTable,
@investigationidout,
@owner,
'Pending Investigation',
'Investigation is pending for ['+ @investigationidout +'] '
@nextstepurl,
@vstatus OUTPUT,
@verror OUTPUT
Run Code Online (Sandbox Code Playgroud) 我有两个存储过程。这个速度非常快(约 2 秒)
CREATE PROCEDURE [schema].[Test_fast]
@week date
AS
BEGIN
declare @myweek date = @week
select distinct serial
from [schema].[tEventlog] as e
join [schema].tEventlogSourceName as s on s.ID = e.FKSourceName
where s.SourceName = 'source_name'
and (e.EventCode = 1 or e.EventCode = 9)
and cast(@myweek as datetime2(3)) <= [Date]
and [Date] < dateadd(day, 7, cast(@myweek as datetime2(3)))
END
Run Code Online (Sandbox Code Playgroud)
而这个运行缓慢(~ 2 小时):
create PROCEDURE [schema].[Test_slow]
@week date
AS
BEGIN
select distinct serial
from [schema].[tEventlog] as e
join [schema].tEventlogSourceName as s on s.ID …Run Code Online (Sandbox Code Playgroud) performance sql-server stored-procedures execution-plan parameter query-performance
今天,当我从 ASP.NET 网页运行时,我遇到了一个存储过程超时(花费超过 30 秒)的问题,但从 SSMS 运行时执行得很快(花费了 5 秒)。
在怀疑参数嗅探是罪魁祸首后,我屏蔽了输入参数,查询执行得更快。
我的问题是:为什么会发生这种情况?
这个系统已经投入生产超过 5 年了,这是我们第一次在我们的存储过程中看到这样的事情。这是“数据库磨损”吗?
我们已经解决了这个问题,所以这没什么大不了的,但我只是好奇为什么会发生这种情况。
performance sql-server stored-procedures parameter query-performance
我在 PostgreSQL 9.5 中编写了一个 PL/pgSQL 函数。它编译得很好,但是当我从 pgAdmin3 调用它时,它给了我一个错误。似乎用函数中传递的参数替换列的动态查询不起作用。
下面是我的功能:
CREATE OR REPLACE FUNCTION insertRecordsForNotification(username text, state text, district text, organizationId text, bloodGroup text, status text, approveRejectStatus text, emailSubject text, emailBody text, notificationStatus text) RETURNS boolean AS $$
DECLARE
id int;
r moyadev.user%rowtype;
_where text :=
concat_ws(' AND '
, CASE WHEN state IS NOT NULL THEN 'state = $2' END
, CASE WHEN district IS NOT NULL THEN 'district = $3' END
, CASE WHEN bloodGroup IS NOT NULL THEN …Run Code Online (Sandbox Code Playgroud) 上下文正在从其余服务器连接到 Postgres 数据库。
考虑一个假设的代表性示例:我希望能够获取帐户创建日期比任意值早/新的名称列表。
在下面的示例查询中,表结构很简单 -name是 type text,并且creation_date是 type timestamp。所以当我做类似的事情时
server_pg_module:query("select name from new_table where
current_timestamp - creation_date < '6 days'")
Run Code Online (Sandbox Code Playgroud)
它工作得很好。但我真正想做的是6 days从服务器获取该值。所以我尝试像
server_pg_module:query("select name from new_table where
current_timestamp - timestamp < $1", ["6 days"]
Run Code Online (Sandbox Code Playgroud)
它抛出一个错误。我试过'6 days',"'6 days'"以及其他一些混合物,都抛出错误。所以为了检查我添加了一个新interval的类型列interval并尝试了一个查询
server_pg_module:query("insert into new_table (name, interval) values ($1, '3 day')", ["fooo"]).
Run Code Online (Sandbox Code Playgroud)
哪个有效,但是
server_pg_module:query("insert into new_table (name, interval) values ($1, $2)", ["fooo", "3 days"]).
Run Code Online (Sandbox Code Playgroud)
休息。为了更好的衡量,除了"'3 days'"上面提到的混合物之外,我还尝试过 …
问题目前影响 C#/.NET、基于 ADO.NET 和 SQL Server 2008 R2 的 DB 访问,但我认为它也适用于其他数据库。
我注意到系统的一些旧模块具有非最佳 SQL 查询,使用多个串联的值字符串而不是参数占位符。他们对表进行轮询,例如每 10 秒一次,以获取在过去几分钟内添加的项目,从而在每次执行时生成新的查询计划。
它们的性能还不错,没有 SQL 注入风险(没有 Web/用户表单),它们很旧,将它们的查询更改为正确的参数化需要做很多工作。我建议做这个改变,但有争论说这会浪费时间,其他事情更重要。
编辑:数据库应该使用大部分参数化查询(所有较新的模块都使用)运行,所以我想避免“优化临时”选项。部分参数化查询无论如何都会创建一个计划。在临时优化模式下运行时是否有缺点,主要是参数化查询?
对我来说,这些旧模块似乎占用了数据库资源的很大一部分,尽管它们很少。随着时间的推移,即使是这种类型的单个模块也会创建数千个查询计划,而所有较新的模块加在一起则更少。
更改这些是否重要,还是我可以将它们保留在它们的状态,仅在当前/未来模块中使用优化/参数化查询?
SQL 是这样的:
select ItemId, ItemName from Items
where ItemType=3 and ItemCreator=1234
and ItemDate >= '2013-11-23 12:30:00'
Run Code Online (Sandbox Code Playgroud)
其中值会有所不同,日期是几分钟之前。在少数情况下,日期已更改为“@startDate”之类的参数,以避免出现格式问题,但 ItemType 和 ItemCreator 值仍然是串联字符串。
在使用 DMV 或 Activity Monitor(最近昂贵的查询 - 计划计数列)监视查询计划时,我注意到其中一些查询在缓存中有 8000 多个等效的查询计划:
select count(*), query_plan_hash
from sys.dm_exec_query_stats
group by query_plan_hash
order by count(*) desc
Run Code Online (Sandbox Code Playgroud)
然后使用 sys.dm_exec_query_plan 上的 CROSS APPLY 选择计划 XML,并通过查询计划哈希选择计划句柄。
编辑/临时结论: 似乎最好让非常旧的应用程序保持原样,即使在创建大量临时查询时也是如此。我最担心的是,大量的一次性临时查询会导致好的、多用途的参数化和准备好的查询计划从缓存中被驱逐。这不会发生,因为当清理完成时,临时计划首先被驱逐,其他计划根据复杂性、使用次数等因素进行评级。因此,无论有多少使用率,参数化查询都可能被保留临时或部分参数化的计划大量涌入。临时优化减少了计划大小(实际上,第一次使用时没有存储真正的计划),但可能会保留更多计划,使用类似的内存(这是正确的吗?)。即使是部分参数化的 SQL(避免本地格式问题的 DateTime 参数)如果不再使用,也会很快被驱逐,即使使用 sp_executesql 发送,这会强制参数化和计划缓存。拥有大量(5000 …
我之前曾在 SQL Server 环境中工作过,其中日志记录是我们存储过程的一部分,用于捕获执行开始/结束、参数值和错误消息,我发现这非常有用,并且是我希望在新环境中引入的内容。
用于此日志记录的表如下所示,使用语句将参数捕获INSERT到表中,并将 with 值隐式转换为NVARCHAR。
CREATE TABLE dbo.Execution
(
Id INT IDENTITY(1,1) NOT NULL
, SchemaName NVARCHAR(128) NOT NULL
, ProcedureName NVARCHAR(128) NOT NULL
, ExecutionStart DATETIME NOT NULL
, ExecutionEnd DATETIME NULL
, ExecutionFailed BIT NOT NULL
)
CREATE TABLE dbo.ExecutionError
(
Id INT IDENTITY(1,1) NOT NULL
, ExecutionId INT NOT NULL
, CustomErrorMessage NVARCHAR(8000) NULL
, SqlErrorMessage NVARCHAR(8000) NULL
)
CREATE TABLE dbo.ExecutionParameter
(
Id INT IDENTITY(1,1) NOT NULL
, ExecutionId INT …Run Code Online (Sandbox Code Playgroud) 我知道如何编写带有输出参数的存储过程。但我不知道为什么我会使用它而不是仅仅使用一个简单的SELECT语句。一个普通的存储过程仍然可以在网格中返回一个输出(见下面的例子)。
任何人都可以举一个真实的例子,我可以在没有输出参数的情况下使用带有输出参数的 SP 而不是 SP 吗?
-- Using output parameter
SELECT @var = COUNT(*) FROM table1 WHERE gender = @gender...
-- Without output parameter
SELECT COUNT(*) FROM table WHERE gender = @gender...
Run Code Online (Sandbox Code Playgroud) 我已使用以下语法在我们的一台服务器上运行sp_WhoIsActive:
sp_whoisactive @get_plans = 1, @show_sleeping_spids = 0, @get_outer_command = 1, @get_locks = 1
Run Code Online (Sandbox Code Playgroud)
并用sql_command(显示的列@get_outer_command设置为1)找到了一个spid,如下所示
(@p1 int,@p2 int)
Exec MyDatabase.MyProc @p1 @p2
Run Code Online (Sandbox Code Playgroud)
当我尝试在我的测试 Adventureworks 数据库上使用此语法运行查询时:
(@be int)
SELECT *
FROM Person.Person
WHERE BusinessEntityID = @be
Run Code Online (Sandbox Code Playgroud)
我收到错误
消息 1050,级别 15,状态 1,第 1 行 此语法仅适用于参数化查询。消息 137,级别 15,状态 2,第 4 行 必须声明标量变量“@FN”。
所以这似乎与参数化查询有关。这是有道理的,因为变量 @be 永远不会被设置为一个值
这里发生了什么?
parameter ×10
sql-server ×6
performance ×2
postgresql ×2
cache ×1
datatypes ×1
dynamic-sql ×1
interval ×1
logging ×1
plpgsql ×1
syntax ×1
t-sql ×1