对于一份报告,我正在查询用户假设必须根据百分比选择 TOP 值或固定行数。
我有两个想法
根据传递的参数调用两个不同的子存储过程。
if @param ='percent'
begin
exec sp_data_TOP_by_Percent
end
if @param ='perRow'
begin
exec sp_data_TOP_by_PerRow
end
Run Code Online (Sandbox Code Playgroud)
另一个想法是使动态 TSQL 查询像这样
declare @command nchar(max)
select @command = 'select top(10) '
+ case @param
when 'percent' then percent
else ' '
end
+ ' * '
+ 'from table
order by 1';
exec sp_executesql @command
Run Code Online (Sandbox Code Playgroud)
像这样的事情有第三种解决方案吗?
什么是更好的方法?第一个避免动态 TSQL,但在两个地方更难维护代码。我使用 MSSQL2005 作为数据库。
鉴于以下存储过程,我能否在提供的附加WHERE条件下防止 SQL 注入?
CREATE PROCEDURE [dbo].[ProtectDynamicWhereClause]
(@TableName varchar(50),
@OldestRecordDate varchar(15),
@WhereCondition varchar(250) = NULL)
AS
BEGIN
-- Protect the table name from SQL Injection.
DECLARE @TableNameClean varchar(150) = QUOTENAME(@TableName)
DECLARE @sql nvarchar(4000)
SET @sql =
N'
SELECT * FROM ' + 'dbo.' + @TableNameClean
+ ' WHERE EntryAge > DATEDIFF(year, @OldestRecordDate, GETDATE()) '
IF (@WhereCondition IS NOT NULL)
BEGIN
SET @sql = @sql + ' AND ' + @WhereCondition
END
EXEC sp_executesql @sql, N'@TableNameClean varchar(50), @OldestRecordDate varchar(15)',
@TableNameClean …Run Code Online (Sandbox Code Playgroud) 我有一个函数,我需要获取一个配置参数并将其分配给我稍后将在函数中使用的变量。问题是当配置参数不被识别(因为它还不存在)时,函数就会死亡。我想评估是否可以分配变量,如果不能为其设置空值。
这是我尝试过的:
DECLARE
conf_param text;
num integer;
BEGIN
SELECT current_setting('the_setting') INTO conf_param;
-- here is where dies when the_setting is not recognized!
IF FOUND THEN
num := conf_param::integer;
ELSE
num := NULL;
END IF;
-- more stuff
Run Code Online (Sandbox Code Playgroud)
我不确定我使用Found的方式是否需要。
我在一个新职位上,被告知要实现一个存储过程,该过程将接受用户 ID 列表并更新一个标志。
当我建议使用表值参数(数组模拟)时,我被告知要实现如下所示,因为这是以前的做法。我不是 DBA,但我是一名全栈开发人员,这对我来说很有趣。
仅供参考 - 用户 ID 实现为类型 int
CREATE PROCEDURE [dbo].[UpdateUsers]
@rgIDs varbinary(max) -- contains several ids
AS
DECLARE @tblTmp TABLE (ID int PRIMARY KEY)
DECLARE @ich int, @cch int, @ID int
SET @cch = DATALENGTH (@rgIDs)
SET @ich = 1
WHILE (@ich < @cch)
BEGIN
SET @ID = SUBSTRING (@rgIDs, @ich, 4)
UPDATE dbo.Users u
SET isUpdated = 1
WHERE u.ID = @ID
SET @ich = @ich + 4
END
Run Code Online (Sandbox Code Playgroud)
不是表值类型在这里工作得更好吗?更具可读性、性能、更不容易出错等......?
我相信我将使用 SQL Server 2012 或 …
是否有发布的明确列表显示在调用 sp_executesql 时可以和不能参数化的内容。
例如,谓词可以,表名不能。TOP 中的行数可以:
exec sp_executesql @stmt =
N'SELECT TOP(@n) a, b
FROM (VALUES(1,2)) v(a,b)',
@params = N'@n int',
@n = 10
Run Code Online (Sandbox Code Playgroud)
MAXDOP 不能:
exec sp_executesql @stmt =
N'SELECT TOP(10) a, b
FROM (VALUES(1,2)) v(a,b)
OPTION (MAXDOP @n)',
@params = N'@n int',
@n = 10
Run Code Online (Sandbox Code Playgroud)
消息 102,级别 15,状态 1,第 8 行“@n”附近的语法不正确。
我想还有更多的例子说明什么有效,什么无效。我正在寻找一个权威列表来消除反复试验。
我有一个存储过程,用可选参数@Param1 int = NULL 说“测试”。在该过程中,@Param1 的值用于更新某个表中某个列的值,如果调用者提供了一个值。如果未提供该参数,则不会更新该列。不幸的是,该列允许 NULL,因此调用者无法将列值设置为 NULL。所以,问题是:程序是否能够区分以下两个调用?
EXEC Test -- 预期含义:不更新列
EXEC Test @Param1 = NULL -- 预期含义:将列设置为 NULL
当然,程序可以检查是否@Param1 IS NULL。但是它可以确定是否已经提供了参数吗?
我发现,通过查询存储,一个查询平均执行 297582 次逻辑读取。
我想看看我是否能够稍微调整该查询,然后尝试再次执行该查询以查看是否有任何改进。
问题是我在缓存计划中找不到编译参数值。
我错过了什么吗?也许是一些阻止参数值缓存的原因/设置?
即使我以 XML 格式打开执行计划,我也找不到参数。
附加信息:查询由第三方应用程序执行,该应用程序准备语句,然后使用sp_prepare和执行它们sp_execute。
sql-server execution-plan parameter plan-cache sql-server-2016
我有一些参数化的查询,但它们每次仍在创建一个新的执行计划。我正在使用 SQL Server 2016。
查询如下:
(@P1 varchar(1043),@P2 varchar(6))
UPDATE table
SET FILEDATA=@P1
WHERE FILEID=@P2
Run Code Online (Sandbox Code Playgroud)
这个查询没有使用缓存中已经生成的执行计划,而是每次都创建一个新计划。
我使用 rpc_completed 事件来捕获执行的 sproc。我也是通过以下方式查看语句和传递的参数:
右键扩展事件 -> Watch Live Data 最后看到语句+参数
但是我想以表格格式查看捕获的数据,但我无法实现它。当我在查询下运行时,它显示没有参数的语句。如何查看表格中的参数?需要你的建议。
IF OBJECT_ID('tempdb..#capture_waits_data') IS NOT NULL
DROP TABLE #capture_waits_data
SELECT CAST(target_data as xml) AS targetdata
INTO #capture_waits_data
FROM sys.dm_xe_session_targets xet
JOIN sys.dm_xe_sessions xes
ON xes.address = xet.event_session_address
WHERE xes.name = 'LongRunningQueries'
AND xet.target_name = 'ring_buffer';
--*/
/**********************************************************/
SELECT
CONVERT(datetime2,SWITCHOFFSET(CONVERT(datetimeoffset,xed.event_data.value('(@timestamp)[1]', 'datetime2')),DATENAME(TzOffset, SYSDATETIMEOFFSET()))) AS datetime_local,
xed.event_data.value('(@name)[1]', 'varchar(50)') AS event_type,
xed.event_data.value('(data[@name="statement"]/value)[1]', 'varchar(max)') AS statement,
xed.event_data.value('(data[@name="duration"]/value)[1]', 'bigint')/1000 AS duration_ms,
xed.event_data.value('(data[@name="physical_reads"]/value)[1]', 'bigint') AS physical_reads,
xed.event_data.value('(data[@name="logical_reads"]/value)[1]', 'bigint') AS logical_reads
FROM #capture_waits_data
CROSS APPLY targetdata.nodes('//RingBufferTarget/event') AS xed …Run Code Online (Sandbox Code Playgroud) 我有一个以以下结尾的函数:
INSERT INTO configuration_dates (
cols...
) VALUES (
values...
) RETURNING id INTO ret_id;
RETURN ret_id;
Run Code Online (Sandbox Code Playgroud)
我想删除该INTO ret_id部分,而是执行以下操作:
RETURN (INSERT INTO configuration_dates (
weekly_date_configuration_id,
"from",
"to",
price,
activity_configuration_id
) VALUES (
wdc_id,
from_ts,
from_ts + wdc.duration,
wdc.price,
wdc.activity_configuration_id
) RETURNING id);
Run Code Online (Sandbox Code Playgroud)
但我还没有找到如何实现这一点。
编辑:添加整个功能
CREATE FUNCTION make_date_from_configuration(wdc_id UUID, from_date DATE)
RETURNS INTEGER AS $$
DECLARE
from_dow INT := EXTRACT(isodow FROM from_date); -- day of the week (1 - 7)
wdc weekly_date_configurations;
from_ts TIMESTAMP;
ret_id INTEGER;
BEGIN
SELECT * …Run Code Online (Sandbox Code Playgroud) 我们有一个用于开发的数据库服务器,它有数百个数据库实例,用于我们应用程序的不同分支/构建。我们需要一个特殊的实例NLS_CALENDAR='Thai Buddha'来测试特定的错误。
我们已经建立了一个数据库并将NLS_CALENDAR='Thai Buddha'设置包含在init.ora. 但是,我们仍然得到'GREGORIAN'for NLS_CALENDAR,因为环境变量会覆盖init.ora.
NLS_CALENDAR 值设置如下:
NLS_SESSION_PARAMETERS: 'GREGORIAN'
NLS_INSTANCE_PARAMETERS: 'Thai Buddha'
NLS_DATABASE_PARAMETERS: 'GREGORIAN'
ALTER SESSION不是一个选项,因为这样我们就必须修改我们的应用程序代码以ALTER SESSION在用户登录时发出一个(这是不可能的,因为我们已经在不同的机器上部署了多个客户端)。修改环境设置也不是一个选项,因为在同一主机上运行着其他数据库实例。
我试过了ALTER SYSTEM,但它给出了以下 oracle 错误:
ORA-02096: 不能使用此选项修改指定的初始化参数
我们如何让单个数据库实例忽略环境设置?或者有没有其他方法可以让我们的实例'Thai Buddha'在NLS_CALENDAR设置时默认使用?
我有下面的代码,我正在使用参数,但它仍然生成许多重复的 SQL 执行计划。请问出了什么问题以及如何修复?
string cmdString = @"INSERT INTO tb_RA_GLID (glid_StoreNumber,
glid_StoreName,
glid_FirstBusinessDate,
glid_LastBusinessDate,
glid_DateCreated,
glid_TimeCreated,
glid_ExportVersion,
glid_GLMappingVersion,
glid_POSModelOrType,
glid_POSVersion)
VALUES (@StoreNumber , @StoreName , @FirstBusinessDate , @LastBusinessDate , @DateCreated , @TimeCreated , @ExportVersion , @GLMappingVersion , @POSModelOrType , @POSVersion );
"; //SELECT SCOPE_IDENTITY();";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.ConnectionString = connectionString;
using (SqlCommand comm = new SqlCommand())
{
comm.Connection = conn;
comm.CommandText = cmdString;
comm.Parameters.AddWithValue("@StoreNumber", columns[1]);
comm.Parameters.AddWithValue("@StoreName", columns[2]);
comm.Parameters.AddWithValue("@FirstBusinessDate", DateTime.ParseExact(columns[3], "yyyyMMdd", CultureInfo.InvariantCulture));
comm.Parameters.AddWithValue("@LastBusinessDate", DateTime.ParseExact(columns[4], "yyyyMMdd", CultureInfo.InvariantCulture));
comm.Parameters.AddWithValue("@DateCreated", DateTime.ParseExact(columns[5], …Run Code Online (Sandbox Code Playgroud) parameter ×12
sql-server ×9
t-sql ×3
dynamic-sql ×2
plan-cache ×2
plpgsql ×2
postgresql ×2
array ×1
functions ×1
oracle ×1
security ×1