0

我正在尝试从我的 MS SQL 数据库运行存储过程。存储过程来自汽车配件商店的 POS(销售点系统)的数据库 - 因此该过程被正确编写并且已被证明可以与 POS 系统一起使用。

尝试运行此存储过程时,我不断收到错误 - SQLSTATE [HY093] - 无效的参数号:超出范围的变量数与令牌数不匹配。

这是我的PHP代码

$db = new PDO($dsn, $user, $password);

$stmt = $db->prepare("CALL insertworkorder(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); ");

$WorkOrderID = 4;
$StoreNumber = 4;
$YardNumber = 4;
$WorkOrderNumber = 3;
$EstimateNumber = '4';
$AccountNumber = 4;
$CustomerNumber = 4;
$CreatedBy = 5;
$DeliveryDate = 4332;
$BillToBusinessName = 'example';
$BillToContactName = 'example';
$BillToAttentionLine = 'example';
$BillToAddress1 = 'example';
$BillToAddress2 = 'example';
$BillToCity = 'example';
$BillToCounty = 'example';
$BillToStateOrProvince = 'example';
$BillToPostalCode = 'example';
$BillToCountry = 'USA';
$BillToContactFAX = 5466;
$BillToContactPhone = example;
$BillToContactOtherPhone = v; 
$BillToContactEMail = 'example@example.net';
$ShipToBusinessName = 'example';
$ShipToContactName = 'example';
$ShipToAttentionLine = 'example';
$ShipToAddress1 = 'example';
$ShipToAddress2 = 'example';
$ShipToCity = 'example';
$ShipToCounty = 'USA';
$ShipToStateOrProvince = 'CT';
$ShipToPostalCode = 'example';
$ShipToCountry = 'USA';
$ShipToContactFax = 'example';
$ShipToContactPhone = 'example';
$ShipToContactOtherPhone = 'example';
$ShipToContactEMail = '';
$ShipVIA = '22';
$CustomerPO = '22';
$WorkOrderStatus = '22';
$WorkOrderNotes = '2';
$Amount = '2';
$TotalDiscountAmount = '2';
$TotalFreightAmount = '2';
$ApplyCustomerTaxRate = '22';
$TotalFreightTaxAmount = '22';
$FreightIsTaxable = '2';
$GSTTaxExempt = '22';
$TotalPartsAmount = '22';
$TotalServicesAmount = '22';
$TotalCoreAmount = '';
$TotalLineItemTaxAmount = '22';
$OrderSource = 'website';
$TrackingNumber = '1226412258223';
$ReasonForVoid = '2';
$EComRequestID = 22;
$CurrentUserID = 22;
$PaypalTransactionID = '3';
$TaxExemptID = '3';
$LegalTraceID = '3';
$BillToContactPhoneExt = '3';
$BillToContactOtherPhoneExt = '3';
$ShipToContactPhoneExt = '3';
$ShipToContactOtherPhoneExt = '3';


$stmt->bindValue(':@StoreNumber', $StoreNumber, PDO::PARAM_INT); //REQUIRED
$stmt->bindValue(':@YardNumber', $YardNumber, PDO::PARAM_INT); //REQUIRED
$stmt->bindValue(':@EstimateNumber', $EstimateNumber, PDO::PARAM_STR);
$stmt->bindValue(':@AccountNumber', $AccountNumber, PDO::PARAM_INT); //REQUIRED
$stmt->bindValue(':@CustomerNumber', $CustomerNumber, PDO::PARAM_INT); //REQUIRED
$stmt->bindValue(':@CreatedBy', $CreatedBy, PDO::PARAM_INT); //REQUIRED
$stmt->bindValue(':@DeliveryDate', $DeliveryDate, PDO::PARAM_INT);
$stmt->bindValue(':@BillToBusinessName ', $BillToBusinessName, PDO::PARAM_STR);
$stmt->bindValue(':@BillToContactName', $BillToContactName, PDO::PARAM_INT);
$stmt->bindValue(':@BillToAttentionLine ', $BillToAttentionLine , PDO::PARAM_STR);
$stmt->bindValue(':@BillToAddress1', $BillToAddress1, PDO::PARAM_STR);
$stmt->bindValue(':@BillToAddress2 ', $BillToAddress2 , PDO::PARAM_STR);
$stmt->bindValue(':@BillToCity', $BillToCity, PDO::PARAM_STR);
$stmt->bindValue(':@BillToCounty', $BillToCounty, PDO::PARAM_STR);
$stmt->bindValue(':@BillToStateOrProvince', $BillToStateOrProvince, PDO::PARAM_STR);
$stmt->bindValue(':@BillToPostalCode', $BillToPostalCode, PDO::PARAM_STR);
$stmt->bindValue(':@BillToCountry', $BillToCountry, PDO::PARAM_STR);
$stmt->bindValue(':@BillToContactFAX', $BillToContactFAX, PDO::PARAM_STR);
$stmt->bindValue(':@BillToContactPhone', $BillToContactPhone, PDO::PARAM_STR);
$stmt->bindValue(':B@illToContactOtherPhone', $BillToContactOtherPhone, PDO::PARAM_STR);
$stmt->bindValue(':@BillToContactEMail', $BillToContactEMail, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToBusinessName', $ShipToBusinessName, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToContactName', $ShipToContactName, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToAttentionLine', $ShipToAttentionLine, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToAddress1', $ShipToAddress1, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToAddress2', $ShipToAddress2, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToCity', $ShipToCity, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToCounty', $ShipToCounty, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToStateOrProvince', $ShipToStateOrProvince, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToPostalCode', $ShipToPostalCode, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToCountry', $ShipToCountry, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToContactFax', $ShipToContactFax, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToContactPhone', $ShipToContactPhone, PDO::PARAM_STR);
$stmt->bindValue(':@ToContactOtherPhone', $ShipToContactOtherPhone, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToContactEMail', $ShipToContactEMail, PDO::PARAM_STR);
$stmt->bindValue(':@ShipVIA', $ShipVIA, PDO::PARAM_STR);
$stmt->bindValue(':@CustomerPO', $CustomerPO, PDO::PARAM_STR);
$stmt->bindValue(':@WorkOrderStatus', $WorkOrderStatus, PDO::PARAM_STR);
$stmt->bindValue(':@WorkOrderNotes', $WorkOrderNotes, PDO::PARAM_STR);
$stmt->bindValue(':@Amount', $Amount, PDO::PARAM_STR); //REQUIRED
$stmt->bindValue(':@TotalDiscountAmount', $TotalDiscountAmount, PDO::PARAM_STR); //REQUIRED
$stmt->bindValue(':@TotalFreightAmount', $TotalFreightAmount, PDO::PARAM_STR);
$stmt->bindValue(':@ApplyCustomerTaxRate', $ApplyCustomerTaxRate, PDO::PARAM_STR); //REQUIRED
$stmt->bindValue(':@TotalFreightTaxAmount', $TotalFreightTaxAmount, PDO::PARAM_STR); //REQUIRED
$stmt->bindValue(':@FreightIsTaxable', $FreightIsTaxable, PDO::PARAM_BOOL); //REQUIRED
$stmt->bindValue(':@GSTTaxExempt', $GSTTaxExempt, PDO::PARAM_BOOL); //REQUIRED
$stmt->bindValue(':@TotalPartsAmount', $TotalPartsAmount, PDO::PARAM_STR);
$stmt->bindValue(':@TotalServicesAmount', $TotalServicesAmount, PDO::PARAM_STR); //REQUIRED
$stmt->bindValue(':@TotalCoreAmount', $TotalCoreAmount, PDO::PARAM_STR);
$stmt->bindValue(':@TotalLineItemTaxAmount', $TotalLineItemTaxAmount, PDO::PARAM_STR);
$stmt->bindValue(':@OrderSource', $OrderSource, PDO::PARAM_STR);
$stmt->bindValue(':@TrackingNumber', $TrackingNumber, PDO::PARAM_STR);
$stmt->bindValue(':@ReasonForVoid', $ReasonForVoid, PDO::PARAM_STR);
$stmt->bindValue(':@EComRequestID', $EComRequestID, PDO::PARAM_INT);
$stmt->bindValue(':@CurrentUserID', $CurrentUserID, PDO::PARAM_INT);
$stmt->bindValue(':@PaypalTransactionID', $PaypalTransactionID, PDO::PARAM_STR);
$stmt->bindValue(':@TaxExemptID', $TaxExemptID, PDO::PARAM_STR);
$stmt->bindValue(':@LegalTraceID', $LegalTraceID, PDO::PARAM_STR);
$stmt->bindValue(':@BillToContactPhoneExt', $BillToContactPhoneExt, PDO::PARAM_STR);
$stmt->bindValue(':@BillToContactOtherPhoneExt', $BillToContactOtherPhoneExt, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToContactPhoneExt', $ShipToContactPhoneExt, PDO::PARAM_STR);
$stmt->bindValue(':@ShipToContactOtherPhoneExt', $ShipToContactOtherPhoneExt, PDO::PARAM_STR);
$stmt->bindParam(':@WorkOrderID', $WorkOrderID, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT);
$stmt->bindParam(':@WorkOrderNumber', $WorkOrderNumber, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT);

$result = $stmt->execute();

print_r($stmt->errorInfo());

这是sql过程:

ALTER procedure [dbo].[insertworkorder]
    (
    @StoreNumber                int,
    @YardNumber                 int,
    @EstimateNumber             varchar(20),
    @AccountNumber              accountnumber,
    @CustomerNumber             customernumber,
    @CreatedBy                  int,
    @DeliveryDate               datetime,
    @BillToBusinessName         contactlong,
    @BillToContactName          contactlong,
    @BillToAttentionLine        contactlong,
    @BillToAddress1             AddressLong,
    @BillToAddress2             AddressLong,
    @BillToCity                 CityLong,
    @BillToCounty               varchar(25),
    @BillToStateOrProvince      stateorprovince,
    @BillToPostalCode           postalcode,
    @BillToCountry              country,
    @BillToContactFAX           phonenumber,
    @BillToContactPhone         phonenumber,
    @BillToContactOtherPhone    phonenumber,
    @BillToContactEMail         email,
    @ShipToBusinessName         contactlong,
    @ShipToContactName          contactlong,
    @ShipToAttentionLine        contactlong,
    @ShipToAddress1             AddressLong,
    @ShipToAddress2             AddressLong,
    @ShipToCity                 CityLong,
    @ShipToCounty               varchar(25),
    @ShipToStateOrProvince      stateorprovince,
    @ShipToPostalCode           postalcode,
    @ShipToCountry              country,
    @ShipToContactFax           phonenumber,
    @ShipToContactPhone         phonenumber,
    @ShipToContactOtherPhone    phonenumber,
    @ShipToContactEMail         email,
    @ShipVIA                    varchar(20),
    @CustomerPO                 varchar(20),
    @WorkOrderStatus            status,
    @WorkOrderNotes             notes,
    @Amount                     money,
    @TotalDiscountAmount        money,
    @TotalFreightAmount         money,
    @ApplyCustomerTaxRate       boolean,
    @TotalFreightTaxAmount      money,
    @FreightIsTaxable           boolean,
    @GSTTaxExempt               boolean,
    @TotalPartsAmount           money,
    @TotalServicesAmount        money,
    @TotalCoreAmount            money,
    @TotalLineItemTaxAmount     money,
    @OrderSource                char(1),
    @TrackingNumber             varchar(50),
    @ReasonForVoid              varchar(255),
    @EComRequestID              int,
    @CurrentUserID              int,
    @PaypalTransactionID        varchar(30),
    @TaxExemptID                varchar(24),
    @LegalTraceID               varchar(24),
    @BillToContactPhoneExt      PhoneExt,
    @BillToContactOtherPhoneExt PhoneExt,
    @ShipToContactPhoneExt      PhoneExt,
    @ShipToContactOtherPhoneExt PhoneExt,
    @WorkOrderID                int output,
    @WorkOrderNumber            int output
    )
as

    set nocount on

    exec dbo.getnextcounter 'WORKORDER', 'WorkOrderID', @WorkOrderID output
    exec dbo.getnexttransactioncounter @YardNumber, @StoreNumber, 'WORKORDER', 'WorkOrderNumber', @WorkOrderNumber output



    insert dbo.WORKORDER
        (
        WorkOrderID,
        StoreNumber,
        Revision,
        YardNumber,
        WorkOrderNumber,
        EstimateNumber,
        AccountNumber,
        CustomerNumber,
        CreatedBy,
        DeliveryDate,
        DateCreated,
        BillToBusinessName,
        BillToContactName,
        BillToAttentionLine,
        BillToAddress1,
        BillToAddress2,
        BillToCity,
        BillToCounty,
        BillToStateOrProvince,
        BillToPostalCode,
        BillToCountry,
        BillToContactFAX,
        BillToContactPhone,
        BillToContactOtherPhone,
        BillToContactEMail,
        ShipToBusinessName,
        ShipToContactName,
        ShipToAttentionLine,
        ShipToAddress1,
        ShipToAddress2,
        ShipToCity,
        ShipToCounty,
        ShipToStateOrProvince,
        ShipToPostalCode,
        ShipToCountry,
        ShipToContactFax,
        ShipToContactPhone,
        ShipToContactOtherPhone,
        ShipToContactEMail,
        ShipVIA,
        CustomerPO,
        WorkOrderStatus,
        WorkOrderNotes,
        Amount,
        TotalDiscountAmount,
        TotalFreightAmount,
        ApplyCustomerTaxRate,
        TotalFreightTaxAmount,
        FreightIsTaxable,
        GSTTaxExempt,
        TotalPartsAmount,
        TotalServicesAmount,
        TotalCoreAmount,
        TotalLineItemTaxAmount,
        OrderSource,
        TrackingNumber,
        ReasonForVoid,
        EComRequestID,
        IsLastRevision,
        CurrentUserID,
        PaypalTransactionID,
        TaxExemptID,
        LegalTraceID,
        BillToContactPhoneExt,
        BillToContactOtherPhoneExt,
        ShipToContactPhoneExt,
        ShipToContactOtherPhoneExt
        )

    values
        (
        @WorkOrderID,
        @StoreNumber,
        0,                      /* Revision         */
        @YardNumber,
        @WorkOrderNumber,
        @EstimateNumber,
        @AccountNumber,
        @CustomerNumber,
        @CreatedBy,
        @DeliveryDate,
        getdate(),              /* @DateCreated     */
        @BillToBusinessName,
        @BillToContactName,
        @BillToAttentionLine,
        @BillToAddress1,
        @BillToAddress2,
        @BillToCity,
        @BillToCounty,
        @BillToStateOrProvince,
        @BillToPostalCode,
        @BillToCountry,
        @BillToContactFAX,
        @BillToContactPhone,
        @BillToContactOtherPhone,
        @BillToContactEMail,
        @ShipToBusinessName,
        @ShipToContactName,
        @ShipToAttentionLine,
        @ShipToAddress1,
        @ShipToAddress2,
        @ShipToCity,
        @ShipToCounty,
        @ShipToStateOrProvince,
        @ShipToPostalCode,
        @ShipToCountry,
        @ShipToContactFax,
        @ShipToContactPhone,
        @ShipToContactOtherPhone,
        @ShipToContactEMail,
        @ShipVIA,
        @CustomerPO,
        @WorkOrderStatus,
        @WorkOrderNotes,
        @Amount,
        @TotalDiscountAmount,
        @TotalFreightAmount,
        @ApplyCustomerTaxRate,
        @TotalFreightTaxAmount,
        @FreightIsTaxable,
        @GSTTaxExempt,
        @TotalPartsAmount,
        @TotalServicesAmount,
        @TotalCoreAmount,
        @TotalLineItemTaxAmount,
        @OrderSource,
        @TrackingNumber,
        @ReasonForVoid,
        @EComRequestID,
        1,
        @CurrentUserID,                       /* IsLastRevision   */
        @PaypalTransactionID,
        @TaxExemptID,
        @LegalTraceID,
        @BillToContactPhoneExt,
        @BillToContactOtherPhoneExt,
        @ShipToContactPhoneExt,
        @ShipToContactOtherPhoneExt
        )

    set nocount off

    return (0)

感谢您的任何帮助!

瓦斯

4

2 回答 2

1

你有两个主要问题。1)您的查询使用问号占位符,您的->bindValue函数使用命名参数。2)你只有 20 个问号,你试图绑定大约 60 个值(我停止计算大约 40 个左右)。

如果要使用命名参数,则需要执行以下代码:

$stmt = $db->prepare("CALL insertworkorder(:StoreNumber, :YardNumber, ... etc ... ");

$stmt->bindValue(':StoreNumber', $StoreNumber, PDO::PARAM_INT); //REQUIRED
$stmt->bindValue(':YardNumber', $YardNumber, PDO::PARAM_INT);
// ... etc ...

如果要使用问号占位符,请执行以下操作:

$stmt = $db->prepare("CALL insertworkorder(?, ?, ?, ... etc ...");

$stmt->bindValue(1, $StoreNumber, PDO::PARAM_INT);
$stmt->bindValue(2, $YardNumber, PDO::PARAM_INT);
// ... etc ...

您必须确保具有与问号(或命名参数)相同数量的 bindValues 否则您将收到Invalid Parameter number: number out of bound variables does not match number of tokens.错误

于 2013-06-25T03:16:47.233 回答
0

嘿,我知道这是一篇旧帖子 - 但只是我在哪里结束的更新。

在我花了几个小时(另一位员工花了几个小时尝试)之后,我们决定 Microsoft Sql 存储过程不能与使用 PDO 连接器的 PHP 一起工作。

我们最终在 PHP 中创建了一个导出功能,将所有内容转储到 XML 文件中,然后我们开发了一个 Java 程序,该程序在 CRON 中每分钟运行一次,扫描我们的文件夹中的 XML 文件并使用 JDBC 驱动程序执行 Ms SQL 存储过程并传入从 XML 文件中读取内容,然后删除 XML 文件...

不确定他们是否已解决此问题,但根据我的经验,PHP 不适用于 Microsoft SQL 存储过程

干杯

于 2015-04-20T15:23:26.240 回答