2015-11-07 3 views
1

Je suis en train de lier datetime2 paramètre à l'aide SQLBindParameter pour SQL_TYPE_TIMESTAMP type de données ci-dessousComment lier datetime2 (SQL_C_TYPE_TIMESTAMP) en utilisant SQLBindParameter?

SQLBindParameter(hStmt, 7, SQL_PARAM_INPUT, SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, 0, 0, &datetime2, 0, NULL);

aussi essayé ceci:

rc = SQLBindParameter(hStmt, 8, SQL_PARAM_INPUT, SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, SQL_TIMESTAMP_LEN + 1, 7, &rec.datetime2, 0, NULL);

rc est 0

quand j'exceute la requête (INSERT) SQLExecDirect(hStmt, const_cast<wchar_t*>(query.c_str()), SQL_NTS); Je reçois 2 2008 sqlstate erreur indiquant le débordement du champ Datetime;

J'ai cherché un exemple de code sur ce type de données et je n'ai trouvé aucun exemple de travail, y a-t-il un ninja qui a une solution pour ce type? il est très bien pour SQL_TYPE_TIME avec précision 7.

+0

J'ai d'abord pensé qu'il y avait une extension spéciale pour Datetime2 (comme pour time2), mais il n'y en a pas - https://msdn.microsoft.com/fr-fr/library/bb677267. Pouvez-vous montrer les valeurs que vous remplissez dans le 'SQL_TIMESTAMP_STRUCT' qui est lié comme paramètre d'entrée? – erg

+0

Bien sûr, il s'agit de la valeur 'SQL_TIMESTAMP_STRUCT datetime2; datetime2.year = 1999; datetime2.month = 2; datetime2.day = 3; datetime2.hour = 8; datetime2.minute = 20; datetime2.second = 30; datetime2.fraction = 123; ' – Genjutsu

Répondre

1

Je reçois la même erreur dans SQL Server 2014: Si je liaison à l'aide nResult = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_TYPE_TIMESTAMP, SQL_TIMESTAMP, 0, 0, &ts, sizeof(ts), &cbValue); , je reçois:

ERROR; native: 0; state: 22008; msg: [Microsoft][ODBC Driver 11 for SQLerver]Datetime field overflow. Fractional second precision exceeds the scale specified in the parameter binding.

Alors, j'ai essayé d'examiner ce que le serveur en fait attend, avec le code comme ceci:

nResult = SQLPrepare(hstmt, (SQLWCHAR*)L"INSERT INTO tTestTable (myTestCol, d2) VALUES(100, ?)", SQL_NTS); 

SQLSMALLINT DataType, DecimalDigits, Nullable; 
SQLUINTEGER ParamSize; 

nResult = SQLDescribeParam(hstmt, 1, &DataType, &ParamSize, &DecimalDigits, &Nullable); 
if (!SQL_SUCCEEDED(nResult)) 
{ 
    printErrStmt(hstmt); 
} 
std::wcout << L"ParamSize: " << ParamSize << L"; DecimalDigits: " << DecimalDigits << std::endl; 

Ceci affiche:

ParamSize: 27; DecimalDigits: 7

Alors, permet d'essayer avec 27 et 7 et une fraction de 123 - obtenir et je toujours l'erreur:

ERROR; native: 0; state: 22008; msg: [Microsoft][ODBC Driver 11 for SQL erver]Datetime field overflow. Fractional second precision exceeds the scale specified in the parameter binding.

Mais je trouve l'échantillon chez Microsoft: https://msdn.microsoft.com/de-de/library/ff878122%28v=sql.120%29.aspx Cet exemple rend les choses encore plus confuses, comme ils font exactement la même chose? Attendez - la différence est, ils utilisent une fraction de seulement 100 - cela peut-il faire la différence? Oui. Changer la fraction en 100 fait fonctionner les choses. Pourquoi?

Regardons directement SQL Server 2014. Si j'ai inséré une ligne (à partir d'ODBC) avec une fraction de 100 cela s'affiche (dans SQL Server Management Studio) en tant que: 1999-02-03 08:20:30.0000001. Rappelez-vous ce que la fraction est exactement: à partir de la documentation à MS: https://msdn.microsoft.com/en-us/library/ms714556%28v=vs.85%29.aspx

[b] The value of the fraction field is the number of billionths of a second and ranges from 0 through 999,999,999 (1 less than 1 billion). For example, the value of the fraction field for a half-second is 500,000,000, for a thousandth of a second (one millisecond) is 1,000,000, for a millionth of a second (one microsecond) is 1,000, and for a billionth of a second (one nanosecond) is 1.

donc: Une fraction de 100 serait de 100 milliardièmes de seconde, c'est 000,000,100. Mais le champ Datetime2 a une précision de 7. Comme la dernière partie est 00, il n'y a pas d'erreur d'arrondi. Mais si vous passez en 123 ce serait 000,000,123. Cela ne peut pas être stocké dans un datetime avec une précision de 7.. Si nous changeons le 123 en 12300, la chose peut être stockée: Elle correspond à 000,012,300, cela correspond au datetime avec une précision de 7, et SQL Server affiche finalement: 1999-02-03 08:20:30.0000123.

J'espère que cela aide, et j'espère avoir compris et expliqué la fraction-chose juste.