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.
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
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