【问题标题】:creating a view: Php->PDO->postgres PDOStatement::execute(): SQLSTATE[42P18]: Indeterminate datatype创建视图:Php->PDO->postgres PDOStatement::execute(): SQLSTATE[42P18]: Indeterminate datatype
【发布时间】:2021-03-03 21:39:36
【问题描述】:

正常的选择、插入等工作,现在我被困在试图创建一个视图并且占位符似乎存在一些问题,如果我插入一个静态数字而不是占位符,则该行可以工作...我首先尝试没有强制转换,然后是隐式强制转换 (::int),现在是显式强制转换,但它不想工作....

$sql = "CREATE OR REPLACE VIEW allowedlists AS
         SELECT distinct l.id, l.nom FROM listing as l,acl,user2acl
         WHERE userid=cast(:userid as INTEGER) AND acl.id=aclid 
          and value > (select value from acl where name='saisie');";
$stmt = $csh->handler->pdo->prepare($sql); 
if(!$stmt->bindValue(":userid", $_SESSION["userid"],PDO::PARAM_INT))
             print("failed to bind 'userid = ".$_SESSION["userid"]."' as ".PDO::PARAM_INT." to ".print_r($stmt,true)."<br>\n"); 
else print("bound 'userid' to ".$_SESSION["userid"]." of type '".PDO::PARAM_INT."'<br\n>");
print("before create view<br>\n"); 
if(!($viewcreation = $stmt->execute()))
{   
  print("<p style=\"color:red;\">Error: (".$stmt->errorCode()."): ".print_r($stmt->errorInfo(),true)."</p>\n");
  $stmt->debugDumpParams();  
} 
print("after create view<br>\n");

失败:

before create view(1)<br>
<br />
<b>Warning</b>:  PDOStatement::execute(): SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR:  could not determine data type of parameter $1 in <b>/var/www/html/content/listing.php</b> on line <b>16</b><br />
<p style="color:red;">Error: (42P18): Array
(
    [0] => 42P18
    [1] => 7
    [2] => ERROR:  could not determine data type of parameter $1
)       
</p>    
SQL: [209] CREATE OR REPLACE VIEW allowedlists AS SELECT distinct l.id, l.nom FROM listing as l,acl,user2acl WHERE userid=cast(:userid as INTEGER) AND acl.id=aclid and value > (select value from acl where name='saisie');
Params:  1
Key: Name: [7] :userid
paramno=0
name=[7] ":userid"
is_param=1
param_type=1
after create view<br>

似乎我在这里遗漏了明显的东西,但我现在转了 3 天,但我唯一设法建立的是挫败感?

据我所知,占位符绑定得很好,类型看起来也不错,如上所述,如果我用静态数字替换占位符,它可以工作,但不能用占位符:(

【问题讨论】:

  • 您可以删除查询的CAST 函数,因为您已经在 PDO 语句中强制执行整数。
  • 好吧,因为它失败了,所以我添加了演员表,但最初确实没有演员表......而且因为我不想出错,所以我更喜欢加倍......
  • 查询的 select-only 部分是否在 PDO 下使用:userid 参数绑定正确运行?我猜是的,而 DDL 语句没有。我猜想:DDL 语句的选择部分实际上是稍后访问视图时将应用的规则。因此,在定义时传递的参数名称不能在运行时绑定到值,即CREATE VIEW DDL 中的SELECT 查询可能未参数化。
  • 查看@CraigRinger 的深入回答以了解类似问题here
  • 好的,所以简短的回答是'不容易'谢谢你的回答,我得到它是为了创建表或列的名称,我只是天真地希望,因为改变参数在 where 子句中,这可以工作....但可能你是对的,我必须静态引入 id :( 好吧,因为我必须将用户名添加到每个视图,这不是真正的问题,只是没有做安全:(准备好的声明会更令人满意..

标签: php postgresql pdo view


【解决方案1】:

创建 VIEW 是一个 DDL 操作,类似于创建表。因此,它不能被参数化。然后使用“参数化”它,使用参数是select语句的where子句。

create or replace view allowedlists as
   select distinct l.id, l.nom 
     from listing as l,acl,user2acl
         where  acl.id=aclid 
          and value > (select value from acl where name='saisie'); 
... 

select id, nom 
  from allowedlists
 where id = :userid; 
 
 OR       

select id, nom 
  from allowedlists
 where id = cast(:userid as integer); 

由于 where 子句会延迟到从视图中选择,因此可能需要将列添加到创建视图的选择中。由于您没有为所有列加上别名,我​​无法分辨。参数化名称需要类似的方法,但您的选择

【讨论】:

  • 不幸的是,我想制作一个只包含用户可能看到的条目的表格,因此创建一个必须选择用户的视图会破坏这个想法:D 但无论如何感谢,因为参数在where 子句我不认为它适用于 DDL 但 DML....所以我必须创建创建视图以编程方式转义会话存储的 id...
猜你喜欢
  • 1970-01-01
  • 2012-03-03
  • 2016-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-08
相关资源
最近更新 更多