2016-08-19 58 views
5

PDO'nun ISO 8601 biçimli zaman damgalarıyla ilgili bir sorunu var gibi görünüyor. Çalışmaz ISO8601 TSQL DATETIME parametresi PDO ile nasıl bağlanır?

$pdoDB = new PDO('odbc:Driver=ODBC Driver 13 for SQL Server; 
    Server='.DATABASE_SERVER.'; 
    Database='.DATABASE_NAME, 
    DATABASE_USERNAME, 
    DATABASE_PASSWORD 
); 
$pdoDB->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$sql = "INSERT INTO dtest (stamp) VALUES ('2011-03-15T10:23:01')"; 
$stmt = $pdoDB->prepare($sql); 
$params = []; 
$stmt->execute($params); 

:

CREATE TABLE dtest (
    "stamp" DATETIME 
); 

İşleri:

Ben İşte benim basit masam Microsoft® ODBC Driver 13 (Preview) for SQL Server®

kullanarak PHP 7.0.8 çalıştıran Ubuntu 16.04 64 bit den bağlıyorum :

$sql = "INSERT INTO dtest (stamp) VALUES (?)"; 
$stmt = $pdoDB->prepare($sql); 
$params = ['2011-03-15T10:23:01']; 
$stmt->execute($params); 

Fatal error: Uncaught PDOException: SQLSTATE[22018]: Invalid character value for cast specification: 0 [Microsoft][ODBC Driver 13 for SQL Server]Invalid character value for cast specification (SQLExecute[0] at /build/php7.0-lPMnpS/php7.0-7.0.8/ext/pdo_odbc/odbc_stmt.c:260)

Ben T yüzden '2011-03-15T10:23:01''2011-03-15 10:23:01'

$sql = "INSERT INTO dtest (stamp) VALUES (?)"; 
$stmt = $pdoDB->prepare($sql); 
$params = ['2011-03-15 10:23:01']; 
$stmt->execute($params); 

Ama 2 milyon kayıtlarına gece çalışan bir komut dosyası yazıyorum hale silerseniz Bu çalışır, bu yüzden gerçekten ziyade taşımaz olur str_replace('T', ' ', $param)

ait çalışan milyonlarca havai ben de bindParam kullanarak denedim ama aynı hatayı veriyor:

$sql = "INSERT INTO dtest (stamp) VALUES (:tdate)"; 
$stmt = $pdoDB->prepare($sql); 
$date = '2011-03-15T10:23:01'; 
$stmt->bindParam(':tdate',$date,PDO::PARAM_STR); 
$stmt->execute(); 

Bu parametreyi olduğu gibi bağlamak ve yürütmek için zaten var mı? Ben hata iletisi biraz şüpheli çünkü çünkü PDO işini iyi yaptı, ancak bu parametreleştirme olmadan tür dönüştürme işlemek mümkün mantıklı değil SQL Server'dan geliyor gibi görünüyor.


Ben de denedim SQL dönüşüm:

İşleri:

$sql = "INSERT INTO dtest (stamp) VALUES (CONVERT(DATETIME, '2011-03-15T10:23:02', 126))"; 
$stmt = $pdoDB->prepare($sql); 
$params = []; 
$stmt->execute($params); 

Çalışmıyor:

$sql = "INSERT INTO dtest (stamp) VALUES (CONVERT(DATETIME, ?, 126))"; 
$stmt = $pdoDB->prepare($sql); 
$params = ['2011-03-15T10:23:02']; 
$stmt->execute($params); 
+0

Merhaba, bununla herhangi bir şans? – MonkeyZeus

+0

@MonkeyZeus nope, ama ben bütün hafta sonu kapalı oldum, bu yüzden bugün başka bir bıçak almaya gidiyorum. –

+0

İyi şanslar! Nasıl gideceğini bana bildirin – MonkeyZeus

cevap

1

Sen kullanmanız gerekecektir SQL Server en yerleşik içinde convert() işlevini belirtin ve size() vererek re: Eğer bunun işe yaraması için manuel tarih dizesinin sonunda :000 eklemeniz gerekebilir böylece

$sql = "INSERT INTO dtest (stamp) VALUES (CONVERT(DATETIME, '2011-03-15T10:23:01', 126))"; 

belgelere dize sonunda :mmm bahseder.

+0

Cevabınız için teşekkürler, ama aynı hatayı alıyorum '$ sql = '' den INSTERT INTO dtest (damga) DEĞERLER (convert (?, 126))"; 'Ayrıca hazırlıksız deyimin dönüştürme olmadan gayet iyi çalıştığını da unutmayın. $ sql = "Dtest IN INSERT (stamp) DEĞERLER ('2011-03-15T10: 23: 01')"; 'Bir soruna neden olan bağlayıcı süreç. –

+0

Aslında, bu ek bir 'Sözdizimi hatası veya erişim ihlaline neden olur: 102 '@ P1'.' yakınında yanlış sözdizimi –

+0

@JeffPuckettII Whoops! Maalesef soru ayrıntılarınızı daha dikkatli okumalıydım. Yine de garip. Bunun yerine ['bindParam()'] (http://php.net/manual/en/pdostatement.bindparam.php) yerine PARAM_STR' kullanmayı ve işlerin daha iyi olup olmadığını görmeyi düşündünüz mü? – MonkeyZeus

1

Aynı sorunu çözmeye çalışırken yarım gün sonra, odbc bırakarak ve yerine dblib kullanarak sona erdi. Php7.0-sybase paketini kurdum, PDO bağlantımın veri kaynağı ismini uyarladım ve herkes için bir kez çözüldü. Artık her bağlantı çalışıyor.

+0

Teknik olarak, bu belirli bir sorunun cevabı değildir, ama "kabul etmek" için çok cazip olduğum için iyi bir geçici çözüm alternatifi. Haklısın, Sybase sürücülerini o kadar çok seviyorum ki, ODBC'yi çağlarda kullanmıyorum. Ama gelecekte ODBC'ye ihtiyaç duyacak daha fazla projeye (örneğin DB2) sahip olacağımı biliyorum ve umarım birileri buna cevap verebilir. –