Pasar la date al parámetro ADODB.Command desde JavaScript

Usando ADO clásico antiguo, no ADO.NET, ¿cómo se transfiere un valor de date a un procedimiento almacenado desde JavaScript? El JS se ejecuta en una página ASP clásica en IIS7. SQL Server es 2012 (1).

RESUELTO: Ver respuesta a continuación. Para resumir, los resultados volvían a mí a través de un secuenciador JSON que ignoraba las properties con valores de date variantes.

Tengo un procedimiento almacenado en SQL Server:

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

Y tengo un código JavaScript en una página ASP clásica:

 var conn = new ActiveXObject("ADODB.Connection"); var cmd = new ActiveXObject("ADODB.Command"); conn.Open(connectionString); cmd.ActiveConnection = conn; cmd.CommandType = adCmdStonetworkingProc; 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(); 

Lo que obtengo del SP siempre tiene el valor esperado para @n (123, arriba), y siempre tiene null para @d . connectionString debe estar bien porque llama al SP, y definitivamente es el SP que creo que estoy llamando; si hago cambios en él, se reflejan en lo que vuelve.

Obtengo el getVarDate() de la respuesta de Eric Lippert aquí . También probé adDBDate con varios types de datos.

Escribí el SP de testing anterior para fines de testing; es posible que haya notado que no hace mucho trabajo útil. En producción, tengo que pasar una date a un SP existente. Los detalles de ese SP no aportarían mucha claridad a esta pregunta. Si es absolutamente necesario, puedo escribir un envoltorio SP que reciba una date como una cadena y la convierta. Pero quiero entender qué está mal aquí, y ya tenemos bastantes SP semi networkingundantes que saturan la database. Y esa es solo una manera horrible de hacer las cosas.

(1) @@ version = 'Microsoft SQL Server 2012 (SP1) – 11.0.3381.0 (X64) 23 de agosto de 2013 20:08:13 Copyright (c) Microsoft Corporation Enterprise Edition (64 bits) en Windows NT 6.0 (compilation 6002 : Service Pack 2) (hipervisor) '

Lo averigué; Estaba tan equivocado, ni siquiera mencioné la parte que en realidad estaba causando el problema.

rs.Fields.Item("d").Value devuelve una variante de tipo adDBTimeStamp .

Esto está en una ASP que actúa como un service web y devuelve JSON, y el secuenciador JSON que estoy usando solo ignora las properties con los valores de adDBTimeStamp . Todo volvía bien desde la database, y luego se eliminó más tarde.

En realidad resulta que el método CreateParameter de CreateParameter es muy servicial con el event handling las dates.

Asi que:

 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)); }