Pregunta

Tengo un control que, sobre devolución de datos, guarda los resultados del formulario a la base de datos.Rellena los valores para ser salvado por la iteración a través de la cadena de consulta.Así, para el siguiente instrucción SQL (simplificado enormemente por el bien de la discusión)...

UPDATE MyTable
SET MyVal1 = @val1,
    MyVal2 = @val2
WHERE @id = @id

...sería un ciclo a través de la cadena de consulta claves de este modo:

For Each Key As String In Request.QueryString.Keys
    Command.Parameters.AddWithValue("@" & Key, Request.QueryString(Key))
Next

Sin EMBARGO, ahora estoy corriendo en una situación en la que, bajo determinadas circunstancias, algunas de estas variables pueden no estar presentes en la cadena de consulta.Si no pasar a lo largo de val2 en el querystring, me sale un error: System.Data.SqlClient.SqlException: Must declare the scalar value "@val2".

Los intentos para detectar el valor que falta en la instrucción SQL...

IF @val2 IS NOT NULL
UPDATE MyTable
SET MyVal1 = @val1,
    MyVal2 = @val2
WHERE @id = @id

...han fracasado.

¿Cuál es la mejor manera de atacar este?Debe analizar el SQL bloque con RegEx, la exploración de los nombres de las variables que no están presentes en la cadena de consulta?O, ¿hay una forma más elegante de enfoque?

ACTUALIZACIÓN:La detección de valores null en la VB código subyacente de la derrota el propósito de disociación entre el código de su contexto.Prefiero no ensuciar mi función con condiciones para todas las posibles variables que podrían ser aprobadas o no aprobadas.

¿Fue útil?

Solución 3

Después de luchar para encontrar una solución más simple, me di por vencido y escribió una rutina para analizar mi consulta SQL para los nombres de variable:

Dim FieldRegEx As New Regex("@([A-Z_]+)", RegexOptions.IgnoreCase)
Dim Fields As Match = FieldRegEx.Match(Query)
Dim Processed As New ArrayList

While Fields.Success
    Dim Key As String = Fields.Groups(1).Value
    Dim Val As Object = Request.QueryString(Key)
    If Val = "" Then Val = DBNull.Value
    If Not Processed.Contains(Key) Then
        Command.Parameters.AddWithValue("@" & Key, Val)
        Processed.Add(Key)
    End If
    Fields = Fields.NextMatch()
End While

Es un poco de un hack, pero esto me permite mantener mi código felizmente ignorantes de que el contexto de mi consulta SQL.

Otros consejos

Primero de todo, yo sugeriría en contra de añadir todas las entradas en la cadena de consulta como los nombres de los parámetros, no estoy seguro de que esto no es seguro, pero no quería correr ese riesgo.

El problema es que usted está llamando

Command.Parameters.AddWithValue("@val2", null)

En lugar de esto usted debe llamar a:

If MyValue Is Nothing Then
    Command.Parameters.AddWithValue("@val2", DBNull.Value)
Else
    Command.Parameters.AddWithValue("@val2", MyValue)
End If

Actualización:La solución que me dio se basa en la suposición de que se trata de un procedimiento almacenado.Va a dar un valor por defecto es Null para el Almacenado de SQL proc parámetros de trabajo?

Si es sql dinámico, siempre pasan el número correcto de parámetros, si es null o el valor real o especificar los valores por defecto.

Me gusta el uso de la AddWithValue método.

Siempre me especificar SQL predeterminado de los parámetros para los parámetros "opcionales".De esa manera, si está vacía, ADO.NET no se incluyen los parámetros y el procedimiento almacenado que se va a utilizar el valor predeterminado.

Yo no tengo que lidiar con la cuenta de cheques/pasando en DBNull.El valor de esa manera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top