将日期传递给JavaScript中的ADODB.Command参数

时间:2013-12-23 19:11:59

标签: javascript sql sql-server asp-classic ado

使用旧的经典ADO, ADO.NET,如何将日期值从JavaScript传递给存储过程? JS在IIS7上的经典ASP页面中运行。 SQL Server是2012(1)。

已解决:见下面的答案。简而言之,结果是通过JSON字符串找回了我的方式,该字符串化器忽略了具有变量日期值的属性。

我在SQL Server中有一个存储过程:

create procedure test(@n int, @d datetime)
as
begin
    select @n n, @d d;
end;

我在经典ASP页面中有一些JavaScript代码:

var conn = new ActiveXObject("ADODB.Connection");
var cmd = new ActiveXObject("ADODB.Command");

conn.Open(connectionString);

cmd.ActiveConnection = conn;

cmd.CommandType = adCmdStoredProc;
cmd.CommandText = 'dbo.test';

cmd.Parameters.Append(cmd.CreateParameter('@n', adInteger, adParamInput, 4, 123));

var param = cmd.CreateParameter('@d', adDate, adParamInput);

param.Value = (new Date('01/01/2000')).getVarDate();

cmd.Parameters.Append(param);

var rs = cmd.Execute();

我从SP返回的内容始终具有@n(上方123)的预期值,null始终为@dconnectionString必须是好的,因为它确实调用了SP,而且它绝对是我认为我正在呼叫的SP;如果我对它进行更改,它们会反映在返回的内容中。

我从Eric Lippert's answer here获得getVarDate()。我还尝试了adDBDate各种数据类型。

我为测试目的编写了上述测试SP;你可能已经注意到它没有做很多有用的工作。在制作中,我必须将日期传递给现有的SP。该SP的细节不会使这个问题更加清晰。我可以,如果我绝对必须,写一个包装SP,它接收一个日期作为字符串并转换它。但我想了解这里有什么问题,而且我们已经有足够多的半冗余SP使数据库混乱。这只是一种可怕的做事方式。

(1)@@ version ='Microsoft SQL Server 2012(SP1) - 11.0.3381.0(X64)2013年8月23日20:08:13版权所有(c)Microsoft Corporation企业版(64位)在Windows NT 6.0上(Build 6002:Service Pack 2)(Hypervisor)'

1 个答案:

答案 0 :(得分:1)

想出来;我错了,我甚至没有提到导致问题的部分。

rs.Fields.Item("d").Value会返回adDBTimeStamp类型的变体。

这是在作为Web服务并返回JSON的ASP中,而the JSON stringifier I'm using只是忽略具有adDBTimeStamp值的属性。一切都从数据库中恢复正常,然后逐渐被淘汰。

事实证明,ADODB.Command的CreateParameter方法非常适合处理日期。

所以:

var rs = RecordSetToObjArray(cmd.Execute();

//  ...

//  Convert variant dates into something the JSON stringifier groks. 
function GetADOFieldValue(field) {
    switch (field.Type) {
        case adDBTimeStamp:
        case adDate:
        case adDBDate:
        case adDBTime:
        case adFileTime:
            if ('undefined' === '' + field.Value)
                return null;
            return new Date('' + field.Value);

        default:
            return field.Value;
    }
}

//  Given recordset from ADODBCommand.Execute(), return as array of JSON 
//  objects. 
//  Also convert variant dates into something the JSON stringifier groks. 
//  If an SP returns multiple recordsets, that's on you. 
function RecordSetToObjArray(rs) {
    var rtn = [];
    var fieldNames = [];

    for (var i = 0; i < rs.Fields.Count; ++i) {
        fieldNames.push(rs.Fields.Item(i).Name);
    }

    rtn.FieldNames = fieldNames;

    while (!rs.EOF) {
        var rec = {};

        for (var i = 0; i < fieldNames.length; ++i) {
            rec[fieldNames[i]] = GetADOFieldValue(rs.Fields.Item(fieldNames[i]));
        }
        rtn.push(rec);
        rs.MoveNext();
    }

    return rtn;
}

function RecordSetToScalar(rs) {
    if (rs.RecordCount == 0 || rs.Fields.Count == 0)
        return null;
    return GetADOFieldValue(rs.Fields.Item(0));
}