在 Postgres 中,准备好的查询和用户定义的函数是否等同于一种防止 SQL 注入的机制?
一种方法比另一种方法有什么特别的优势吗?
postgresql sql-injection prepared-statement plpgsql functions
我正在使用 mysql,我需要以某种方式使用后面查询中准备好的语句返回的列 curid。我使用准备好的语句,因为正如我所读到的,它是将变量传递给 LIMIT 子句的唯一方法。我在这里有这个存储过程:
DROP PROCEDURE IF EXISTS fixbalance;
CREATE PROCEDURE fixbalance (userid INT)
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE balance INT DEFAULT 0;
DECLARE idcnt INT;
SET idcnt = (SELECT COALESCE(COUNT(id), 0)
FROM coupon_operations
WHERE user_id = userid);
IF idcnt <> 0 THEN
WHILE i <= idcnt DO
BEGIN
SET @iter = i;
SET @user_id = userid;
SET @sql = CONCAT('SELECT id AS curid
FROM coupon_operations
WHERE user_id = ?
ORDER BY id ASC
LIMIT ?, 1'); …
Run Code Online (Sandbox Code Playgroud) 我遇到了开发人员代码,其中 SqlCommand.Prepare() (参见 MSDN)方法在执行 SQL 查询之前被广泛使用。我想知道这样做有什么好处?
样本:
command.Prepare();
command.ExecuteNonQuery();
//...
command.Parameters[0].Value = 20;
command.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
我玩了一点并进行了追踪。调用Prepare()
方法后执行Command,使Sql Server执行如下语句:
declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,N'@id int,@desc text',N'INSERT INTO dbo.testtable (id) VALUES (@id)',@id=20'
select @p1
Run Code Online (Sandbox Code Playgroud)
之后,当 Parameter 获取它的值并被SqlCommand.ExecuteNonQuery()
调用时,将在 Sql-Server 上执行以下操作:
exec sp_execute 1,@id=20
Run Code Online (Sandbox Code Playgroud)
对我来说,这看起来就像语句在Prepare()
执行时被编译。我想知道这样做有什么好处?这是否意味着它被放入计划缓存中,并且可以在使用所需参数值执行最终查询后立即重新使用?
我发现(并在另一个问题中记录了它)使用 SqlParameters 执行的 SqlCommands 总是包含在sp_executesql
过程调用中。这使得 Sql Server 能够独立于参数值存储和重用计划。
关于这一点,我想知道该prepare()
方法是无用的还是过时的,或者我在这里遗漏了什么?
sql-server execution-plan sql-server-2008-r2 prepared-statement plan-cache
我正在开发一个涉及大量数据库写入的应用程序,大约 70% 的插入和 30% 的读取。这个比率还包括我认为是一次读取和一次写入的更新。通过插入语句,多个客户端通过下面的插入语句在数据库中插入数据:
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
Run Code Online (Sandbox Code Playgroud)
问题是我应该使用insert_delay还是使用mysqli_multi_query机制,因为 insert 语句在服务器上使用 ~100% cpu。我在我的数据库上使用 InnoDB 引擎,所以插入延迟是不可能的。服务器上的插入是 ~36k/hr 和 99.89% 读取,我也在使用 select 语句在单个查询中检索数据七次,这个查询在服务器上执行需要 150 秒。我可以使用什么样的技术或机制来完成这项任务?我的服务器内存是 2 GB,我应该扩展内存吗?。看看这个问题,任何建议将不胜感激。
表的结构:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | …
Run Code Online (Sandbox Code Playgroud) 我正在尝试从 PHP 准备一个查询,例如:
pg_prepare($con, "prep", "select * from test where tid in ($1)");
Run Code Online (Sandbox Code Playgroud)
然后执行它:
$strpar = "3,4,6,8,10";
pg_execute($con, "prep", array($strpars));
Run Code Online (Sandbox Code Playgroud)
问题是我无法传递一系列构建为 prepare 期望固定数量参数的值。有没有办法使参数动态?
有人知道我如何列出 SQL Server 实例中的准备好的语句吗?
问题的核心:实际存储过程是实现临时表缓存的唯一机制还是系统存储过程(例如sp_executeSQL
/sp_execute
也利用它们)?
我不是 DBA,所以请少说几句。我们的应用程序发送准备好的语句,从分析器中,我看到运行所有 SQL,sp_prepexec
它是运行sp_prepare
和sp_execute
. 我想要做的是弄清楚我是否从临时表缓存中受益。
我一直在使用带有 object_id() 的本指南来检查行为
https://sqlkiwi.blogspot.com/2012/08/temporary-tables-in-stored-procedures.html
然后这篇博文中的第 3 点表明 EXEC 不能使用临时表缓存,但忽略了 sp_executeSQL 是否可以:http : //blogs.msdn.com/b/turgays/archive/2013/09/18/exec-vs- sp-executesql.aspx
在我通过客户端发送的查询中,我创建了一个简单的临时表。
DECLARE @foo int; -- set by JDBC, unused but required to force a prepared statement
SELECT 1 AS id
INTO #tmp
SELECT OBJECT_ID('tempdb..#tmp');
Run Code Online (Sandbox Code Playgroud)
在探查器中,我可以看到:
declare @p1 int
set @p1=NULL
exec sp_prepexec @p1 output,N'@P1 int',N'declare @foo INT = @P1
SELECT 1 as id
into #tmp
select Object_id(''tempdb..#tmp'');
DROP TABLE #tmp;',1 …
Run Code Online (Sandbox Code Playgroud) sql-server stored-procedures dynamic-sql prepared-statement temporary-tables
问题/问题:获取错误: [Err] 1615 - Prepared statement needs to be re-prepared
我有一个存储过程,其中包含一个准备好的语句和一个视图
DROP PROCEDURE IF EXISTS `sampleProc`;
DELIMITER ;;
CREATE DEFINER = `root`@`localhost` PROCEDURE `sampleProc`()
BEGIN
SET @select = "SELECT * FROM `viewSample` ";
PREPARE stmt FROM @select ;
EXECUTE stmt ;
DEALLOCATE PREPARE stmt ;
END ;;
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
以下调用有时会出错 CALL sampleProc();
可能的解决方法/解决方案
看来最好的解决方案是增加 table_definition_cache 的值,但似乎不起作用,因为它已经从 1400(默认)增加到 16384。 table_open_cache 也增加到 32162
Variable_name Value
table_definition_cache 16384
table_open_cache 32162
table_open_cache_instances 4
Run Code Online (Sandbox Code Playgroud) 我在 MySQL 中运行搜索查询以从产品和价目表表中返回项目。当用户进行搜索查询时,我需要从产品表中获取产品 LEFT JOINED 与来自第二个表(任意数量的卖家)的所有授权/解锁卖家。
我有基本的搜索查询工作,但我无法让“动态左联接”工作。我在准备声明中被告知要这样做,我(a)正在努力(第一次)并且我不知道在工作时把它放在哪里。
我的搜索查询将如下所示:
SELECT articles AS art
<< need to left join here >>
FROM bigtable AS bt
WHERE
a lot of other criteria
Run Code Online (Sandbox Code Playgroud)
这是我想出的准备声明:
SET @sql_text := '
DECLARE strCount INT DEFAULT 1;
SELECT sid, ifnull(pricelist,"BASE"), count(*) AS recs
FROM buyerList AS b
LEFT JOIN sellerList AS s ON s.sid = b.sid AND s.pass = b.pass
WHERE b.bid = ?
SET @string = "LEFT JOIN preislisten AS p";
lj:
LOOP
SET @string = CONCAT( …
Run Code Online (Sandbox Code Playgroud) 我使用的一些存储过程需要根据是否提供了过程输入参数来插入 WHERE 条件。为了避免潜在的注入点,我想对将成为内插标准的一部分的值使用参数绑定。
由于添加到准备好的语句中的条件以及要绑定的参数数量可能因用户输入而异,因此我设计了以下方法来确定将哪些变量传递给 EXECUTE 语句。这有效,但似乎不优雅。
CREATE PROCEDURE foo (IN mandatory INT, IN optional INT, IN optional2 VARCHAR(20))
BEGIN
SELECT
0, '', '', mandatory, optional, optional2
INTO
@params, @sql, @where, @m, @o1, @o2;
IF (@o1 > '' AND @o1 IS NOT NULL) THEN
SET @where = CONCAT(@where, ' AND field = ?');
SET @params = @params + 1;
END IF;
IF (@o2 > '' AND @o2 IS NOT NULL) THEN
SET @where = CONCAT(@where, ' AND field2 = ?');
SET …
Run Code Online (Sandbox Code Playgroud) 如何在 SQL Server 中创建和使用准备好的语句?
在 PostgreSQL 中,您可以执行以下操作:
PREPARE prepared (varchar, varchar, etc) AS
INSERT INTO table(field,field,etc)
VALUES ($1,$2,etc);
EXECUTE (value,value,etc);
Run Code Online (Sandbox Code Playgroud)
在 MySQL 中类似的东西。
我在 SQL Server 中找不到任何示例。我已经看到了一些使用功能的例子,但我不认为这是同样的事情。
谢谢
我使用扩展事件来存储数据库错误,如下所示:
CREATE EVENT SESSION [ErrorCapture]
ON SERVER
ADD EVENT sqlserver.error_reported
(
ACTION
(
sqlserver.client_hostname,
sqlserver.database_id,
sqlserver.sql_text,
sqlserver.username
)
WHERE
(
[severity] >= (11)
)
)
ADD TARGET package0.asynchronous_file_target
(
SET filename='J:\ServerXmlOutput\ErrorCapture.xel'
)
WITH
(
MAX_MEMORY=4096 KB,
EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY=10 SECONDS,
MAX_EVENT_SIZE=0 KB,
MEMORY_PARTITION_MODE=NONE,
TRACK_CAUSALITY=OFF,
STARTUP_STATE=ON
);
Run Code Online (Sandbox Code Playgroud)
这有助于我轻松跟踪导致它们的应用程序。我有类似的东西来跟踪慢查询和其他特殊情况。但是,我从 SQL Server Profiles 中注意到 PHP/Laravel 应用程序不是直接发送一些语句,而是使用 RPC:Completed:它们看起来像准备好的语句,在运行时接收参数。如何扩展我的 ErrorCapture 以包含由通过 RPC:Completed 执行的语句引起的错误?
我想从基于多行 DISTINCT 的 SELECT 语句创建一个表,但 PostgreSQL 不允许我这样做。
我需要创建一个表格,其中的元素之前是从另一个表格中选择的,并且它们都是唯一的。
这是我的尝试:
CREATE TABLE new_name AS (
SELECT DISTINCT(table.field1, table.field2), table.field1, table.field2,
FROM ...
WHERE ...
);
Run Code Online (Sandbox Code Playgroud)
如果我运行这个语句,PostgreSQL 会说:
错误:列“行”具有伪类型记录
我怎么能解决这个问题?
mysql ×5
sql-server ×5
dynamic-sql ×3
postgresql ×3
php ×2
array ×1
functions ×1
innodb ×1
memory ×1
mysql-5.6 ×1
plan-cache ×1
plpgsql ×1
select ×1
view ×1