创建视图:Php->PDO->postgres PDOStatement::execute():SQLSTATE[42P18]:不确定数据类型

创建视图:Php->PDO->postgres PDOStatement::execute():SQLSTATE[42P18]:不确定数据类型,php,postgresql,pdo,view,Php,Postgresql,Pdo,View,正常的选择,插入等工作,现在我被困在试图创建一个视图,似乎有一些占位符的问题,如果我插入一个静态数字,而不是占位符的线工程。。。我先尝试不使用强制转换,然后使用隐式强制转换::int,现在使用显式强制转换,但它不想工作 $sql = "CREATE OR REPLACE VIEW allowedlists AS SELECT distinct l.id, l.nom FROM listing as l,acl,user2acl WHERE useri

正常的选择,插入等工作,现在我被困在试图创建一个视图,似乎有一些占位符的问题,如果我插入一个静态数字,而不是占位符的线工程。。。我先尝试不使用强制转换,然后使用隐式强制转换::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>
似乎我忽略了这里显而易见的东西,但我现在已经三天不停地改变了,但我唯一能做到的就是沮丧


就我所见,占位符绑定很好,类型似乎也很好,如前所述,如果我用一个静态数字替换占位符,它可以工作,但占位符不行:

创建视图是一个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子句延迟到从视图中选择,因此可能需要向select添加列以创建视图。因为你没有给所有栏目都加上别名,所以我说不出来。将名称参数化也需要类似的方法,但是您的select

可能可以删除查询的CAST函数,因为您已经在PDO语句中强制执行了一个整数。由于它失败了,我添加了CAST,但最初确实没有。。。由于我不想出错,我更喜欢双倍化,而不是…查询的select only部分是否在PDO下使用:userid参数绑定正确运行?我想是的,而DDL语句不是。我认为:DDL语句的select部分实际上是一条规则,稍后访问视图时将应用该规则。因此,在定义时传递的参数名不能在运行时绑定到一个值,即创建视图DDL中的SELECT查询可能没有参数化。请参阅@CraigRinger的深入解答以了解类似问题,好的,简短的回答是“不容易”,感谢您的回答,我得到它是为了创建表或列的名称,我只是天真地希望,因为改变参数在where子句中,所以这可以工作。。。。但很可能你是对的,我必须静态地引入id:因为我必须在每个视图中添加用户名,这并不是一个真正的问题,只是需要确保安全:一个准备好的语句会更令人满意..不幸的是,我想制作一个只包含用户可能看到的条目的表,因此,创建一个必须选择用户的视图的想法失败了:D但是无论如何,谢谢,因为参数在where子句中,我认为它不适用于DDL,而适用于DML。。。。因此,我必须以编程方式创建create视图,以转义会话存储id。。。