Mi SqlParameter no está pasando NULL correctamente
-
06-09-2019 - |
Pregunta
Tengo este formulario web C # que tiene tiene un cuadro de selección de fecha. Si la fecha se fija en nada (por defecto) Quiero que pase NULL a la base de datos. Esto sucede dentro de mi consulta parametrizada.
SqlParameter CMActionDate = new SqlParameter();
CMActionDate.ParameterName = "@ActionDate";
if (ActionDate.Equals(""))
{
CMActionDate.Value = System.Data.SqlTypes.SqlDateTime.Null;
}
else
{
CMActionDate.Value = ActionDate;
}
Cuando enciendo la depuración veo que la fecha es de hecho "" por lo que entra en la instrucción IF y establece el actiondate.value a {nulo} como creo que debería.
Sin embargo.
Cuando se pasa entonces a ejecutar la nonquery, hago clic en la lupa y ver esto:
UPDATE table SET [action_date] = '' WHERE [id] = 2488
Lo que me gustaría ver es la siguiente:
UPDATE table SET [action_date] = 'Null' WHERE [id] = 2488
Desde el action_date nunca se mete NULL, entonces el valor en el campo de fecha y hora vuelve a "01/01/1900 12:00:00 AM" y eso es un dolor en sí mismo.
He intentado fijar CMActionDate.Value a los siguientes valores en vano (me da el mismo resultado que el anterior.):
- DBNull.Value;
- "NULL";
- SqlDateTime.Null;
- nulo;
Ayuda.
Editar
Tal vez no estaba claro? Sí, por supuesto, la consulta parametrizada se ve así:
"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' WHERE [id] = " + @CM_id + "";
Pero cuando estoy depurando esta cosa en VS, puse un punto de corte delante derecha ExecuteNonQuery (); para que pueda ver el SQL que está intentando ejecutar. Es ahí donde veo el SQL real y ver la parte en action_date = ''.
¿Le ayuda?
Solución
No se debe ver bien '' o 'nulo'. Si está utilizando correctamente las consultas con parámetros que debe tener este aspecto:
UPDATE tabla SET [action_date] = @ActionDate DONDE [id] = @ID
El punto de una consulta parametrizada es que el valor del parámetro actual es no sustituido directamente en la cadena de consulta.
Su código de consulta debe ser algo como esto:
string sql = "UPDATE table SET [action_date]= @ActionDate WHERE [id]= @CM_id";
using (var cn = new SqlConnection("your connection string here."))
using (var cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@ActionDate", SqlDbTypes.DateTime).Value =
ActionDate.Equals("")? DBNull.Value : DateTime.Parse(ActionDate);
cmd.Parameters.Add("@CM_id", SqlDbTypes.Int).Value = 2488;
cn.Open();
cmd.ExecuteNonQuery();
}
El resultado de este código es que sus parámetros de consulta se envían al servidor como datos. En ningún momento de su código C # nunca vas a ser capaz de ver la cadena de consulta con sus datos sustituidos en: se envía al servidor por separado.
Esto evita cualquier posibilidad de que el servidor de ejecución de un valor de parámetro como el código debido a un error en la desinfección de su valor de parámetro. Los datos están completamente separados, y no necesitan ser limpiados de ese contexto en el primer lugar. También permite al servidor caché y reutilizar el plan de ejecución de la consulta, lo que resulta en un (pequeño) aumento de rendimiento.
Otros consejos
Su consulta establecieron los parámetros debería mostrar
UPDATE table SET [action_date] = @ActionDate WHERE [id] = @id
Y el valor del parámetro debe tener un valor equivalente nula.
Su sql es
"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "'
WHERE [id] = " + @CM_id + "";
Lo que en realidad no tiene sentido. Usted debe dejar a SQL sustituir el @ActionDate y @CM_ID, no construye una consulta SQL dinámico.
Su SQL debe ser literalmente:
String sql = "UPDATE table SET [action_date] = @ActionDate WHERE [id] = @CM_id"
No debe haber ninguna concatenación de cadenas en torno a las variables, y no debe ser envuelto entre comillas.
Su consulta con toda seguridad no se ve como los publicados.
Su @parameter tiene que estar dentro de la cadena, con el fin de ser leído correctamente. Usted está viendo ActionDate = '' porque @ActionDate no existe, lo más probable.
Es necesario algo así como
string sql = "UPDATE CM_Codebase SET [action_date] = @ActionDate WHERE [id] = @CM_id";
Tenga en cuenta que no hay una concatenación de cadenas que tienen lugar.