2016-04-13 35 views
7

konak parametre olarak diziyi yerine nasıl tip int, str, bool ve null değerlerini bağlamak mümkün ama ben dizi türü bağlamak kuramıyorum.
Her iki işlevi de denedim, yani bindValue ve bindParam ancak bunların hiçbiri işe yaramadı. Bunu nasıl yapabilirim?PHP - Hazırlanan açıklamada

// a helper function to map Sqlite data type 
function getArgType($arg) { 
    switch (gettype($arg)) { 
     case 'double': return SQLITE3_FLOAT; 
     case 'integer': return SQLITE3_INTEGER; 
     case 'boolean': return SQLITE3_INTEGER; 
     case 'NULL': return SQLITE3_NULL; 
     case 'string': return SQLITE3_TEXT; 
     default: 
      throw new \InvalidArgumentException('Argument is of invalid type '.gettype($arg)); 
    } 
} 

$sql = "SELECT * FROM table_name WHERE id IN (?)"; 
$params = [[10, 9, 6]]; // array of array 
$dbpath = '/path/to/sqlite.sqlite'; 
$db = new SQLite3($dbPath, SQLITE3_OPEN_READONLY); 
$stmt = $db->prepare($sql); 

try { 
    foreach ($params as $index => $val) { 
     if (is_array($val)) { 
      /************* I am stuck here *************/ 
      $ok = $stmt->bindParam($index + 1, $val); 
      // Using bindValue also didn't worked! 
     } else { 
      $ok = $stmt->bindValue($index + 1, $val, getArgType($val)); 
     } 

     if (!$ok) { 
      throw new Exception("Unable to bind param: $val"); 
     } 
    } 
} catch (Exception $ex) { 
    // NO exception is thrown from bindValue() or bindParam() 
    $reason = "Error in binding statement. " . $ex->getMessage(); 
    die($reason); 
} 

$result = $stmt->execute(); 
$data = []; 
while ($row = $result->fetchArray($mode)) { 
    $data[] = $row; 
} 
var_dump($data); 

Düzenleme: Zaten param dizide soru işaretleri gerekli sayıda tek ? yerine çalıştı, ama sonra benim dizi az değerlere sahip yalnızca çalışıyor! PHP'deki ifadelerin SQLite3'te nasıl hazırlandığının bir sınırlama olduğunu düşünüyorum.

+1

, ama (geçerli örnekte örneğin 3 '?' Ler) Sorgunuzda her değerin yerine bir yer tutucu koymak gerekir inanıyoruz. Ardından her bir değeri diziden bağlayın; veya diziyi 'execute 'içinde geçirin. – chris85

+0

@ chris85: Yalnızca dizinin 1000 öğeden daha az olması durumunda çalışır. Her durumda çalışmak için bir çözüm istiyorum. Teşekkürler. –

+1

'PHP' veya' sqllite' isabet sınır mı? +1000 'POST' değerlerini almaya mı çalışıyorsunuz? – chris85

cevap

8

Malesef bu mümkün değil! Bir diziyi bağlayamazsınız.

  1. dizinin üzerinde yineleme tarafından dizinin
  2. bağlama değer başına bir yer tutucu (?) ile her değeri SQL sorgusu oluşturun:

    sorunun en kolay çözüm aşağıdaki olurdu.

Ama başka bir seçenek (örneğin bir alt SEÇ) bir Java soru bile

More information here (veritabanı türü bu önemli değil çünkü neredeyse aynı konu/sorun da vardır vaka)

DÜZENLEME: Normalde, ciltli parametreler için SQL Limiti yüzden 999 ayarlanır, ancak can change it if you need to sen edilir.

+0

Bu çözümün 999 bir sınırı vardır. 999'dan fazla değere bağlanamıyorum. Php sqlite'deki bu varsayılan sınırı nasıl değiştireceğinize dair ipucu var mı? –

+0

@AtulVaibhav SQLite sınırlarını değiştirebileceğinden emin olun. Daha fazla bilgi [resmi SQLite sayfasında] (https://www.sqlite.org/limits.html). Bu size uygun değilse, cevabımdaki bağlantıdan diğer çözümleri deneyebilirsiniz. – manniL

1

Ekleyebilirsin? Onlar büyük 1000'den iseniz sizin dizideki

Select * from table_a where field in (?,?,?,?,?,?,?,.....) 

öğelerin sayısı kadar tutucu daha sonra iki ya da daha fazla sorgular bölebilirsiniz.

2

Dizileri, IN (?) yan tümcesi için liste olarak bağlayamazsınız. IN listesindeki her değerin, ayrı yer tutucularını alması gerekir.

Bu dinamik yapmak için önce değer dizisini belirleyin ve sonra SQL'i dinamik olarak oluşturun.

Bu kod olacaktır:

$arrayParam = [10, 9, 6]; 
$placeHolders = implode(',', array_fill(0, count($arrayParam), '?')); 
$sql = "SELECT * FROM table_name WHERE id IN ($placeHolders) AND name = ?"; 
// Merge the "array" parameter values with any other parameter values 
// into one non-nested array: 
$params = array_merge($arrayParam, ['myname']); 
// ... 
    foreach ($params as $index => $val) { 
     // No sub arrays allowed: 
     $ok = $stmt->bindValue($index + 1, $val, getArgType($val)); 
     // ... etc 
2

(Uyarı: Bu cevap 'mysql' etiketi kaldırıldı önce yazılmıştır; ben sqlite3 için eğer o addslashes eser bilmiyorum.)

PHP

, bir IN listesi için mukadder değerler dizisi olarak $ liste verilmiştir:

$list = array(1, 2, 'abcd', 'double quote: "', "apostrophe: don't"); 
$ins = implode(', ', array_map(
     function($a) { 
       return "'" . addslashes($a) . "'"; 
        }, $list)); 
echo $sql = "... IN ($ins) ...";; 

verim

... IN ('1', '2', 'abcd', 'double quote: \"', 'apostrophe: don\'t') ... 

(Evet, bu normal bir for döngü ile yapılabilir, array_map ve bir "anonim işlev" kullanmadan.)

Endişelenme; Sayılar ('123') ile ilgili tırnaklar sayısal sütunlar için uygundur.

2

Yapmaya çalıştığınız bir çalışma öneririm. Sorgu sonucunu geçici bir tabloya geçirin.

// a helper function to map Sqlite data type 
function getArgType($arg) { 
     switch (gettype($arg)) { 
      case 'double': return SQLITE3_FLOAT; 
      case 'integer': return SQLITE3_INTEGER; 
      case 'boolean': return SQLITE3_INTEGER; 
      case 'NULL': return SQLITE3_NULL; 
      case 'string': return SQLITE3_TEXT; 
      default: 
       throw new \InvalidArgumentException('Argument is of invalid type '.gettype($arg)); 
     } 
} 
function getTempValues() { 
$sql = "SELECT * FROM `myTemp`"; 
$params = [$in]; // array of array 
$dbpath = '/path/to/sqlite.sqlite'; 
$db = new SQLite3($dbPath, SQLITE3_OPEN_READONLY); 
$stmt = $db->prepare($sql); 
$result = $stmt->execute(); 
    $data = []; 
    while ($row = $result->fetchArray($mode)) { 
     $data[] = $row; 
    } 
    return $data; 
} 
function addToTemp($in) { 
$sql = "SELECT * INTO `myTemp` FROM `table_name` WHERE `id` = ?"; 
$params = [$in]; // array of array 
$dbpath = '/path/to/sqlite.sqlite'; 
$db = new SQLite3($dbPath, SQLITE3_OPEN_READONLY); 
$stmt = $db->prepare($sql); 
if(is_array($in)) { 
foreach($in as $newValue) { 
addToTemp($newValue); 
} 
} else { 
try { 
     foreach ($params as $index => $val) { 
       $ok = $stmt->bindValue($index + 1, $val, getArgType($val)); 
      if (!$ok) { 
       throw new Exception("Unable to bind param: $val"); 
      } 
     } 
    } catch (Exception $ex) { 
     // NO exception is thrown from bindValue() or bindParam() 
     $reason = "Error in binding statement. " . $ex->getMessage(); 
     die($reason); 
    } 

    $stmt->execute(); 
} 
return getTempValues(); 
} 

print_r(addToTemp([10,9,6])); 
SQLLite ile değil tanıdık
İlgili konular