Archivo de la etiqueta: ADO.NET

Posts relacionados con la tecnología de acceso a datos de .NET Framework

VarChar y NVarChar en SQL Server y MySQL el código para VB y C#

Pues eso… lo prometido es deuda y aquí tienes el código que te prometí del ejemplo correspondiente al post anterior (VarChar y NVarChar en SQL Server) para VB y C#.

Este código te permite comprobar que usando VARCHAR también puedes agregar caracteres especiales del idioma español: vocales acentuadas, eñes, etc.

En este ejemplo también uso dos bases de datos (en realidad 3), una de SQL Server y otra de MySQL en un servidor que está en la nube (en un hosting de Internet, concretamente en uno de Domitienda.com que es donde yo tengo mis sitios alojados). La tercera base es una de SLQ Server en mi servidor local (el de SQLEXPRESS).

El diseño del formulario y el código de VB y C#

Este es el formulario en modo de diseño (figura 1):

Figura 1. El formulario en modo de diseño.
Figura 1. El formulario en modo de diseño.

Nota:

En el código tienes la cadena de conexión para las bases de datos que están en «la web» y es posible que dejen de estar disponibles dentro de algún tiempo (no sé si una semana, un mes, un año o un día), así que… si quieres probarlo, usa cuanto antes el código del ZIP que te pondré al final o crea un proyecto a partir de lo que aquí te muestro.

El proyecto está creado con Visual Studio 2019 Preview 4.3 pero debería cargar también en Visual Studio 2017 y utiliza el .NET Framework 4.7.2.

El código para Visual Basic .NET

'------------------------------------------------------------------------------
' Prueba de los tipos de SQL VarChar y NVarChar                     (19/Mar/19)
' Usando base de SQL Server y MySQL
'
'
' (c) Guillermo (elGuille) Som, 2019
'------------------------------------------------------------------------------
Option Strict On
Option Infer On

Imports System.Data
Imports System.Data.SqlClient
' Versión de mysql.data.dll: Connector/Net 6.0.3.0
Imports MySql.Data.MySqlClient

Imports System.Linq


Public Class Form1

    Private inicializando As Boolean = True

    ''' <summary>
    ''' Para las primeras pruebas uso una base local
    ''' </summary>
    Private UsarBaseLocal As Boolean = True

    Private ServerName As String = ".\SQLEXPRESS"
    Private DatabaseName As String = "PruebaVarChar"
    Private UsuarioDB As String = "elGuille_info"
    Private PasswordDB As String = "VarChar_19"

    Private Tabla As String = "VarCharElGuille"
    ' Campos: Fecha, ConVarChar varchar(50), ConNVarChar nvarchar(50)
    ' en MySQL no hay NVARCHAR y uso TEXT(50)

    Private MaxFilas As Integer = 5

    ''' <summary>
    ''' La cadena de conexión a la base de datos
    ''' </summary>
    Private Function CadenaConexionSQL() As String
        ConectarSQL()

        Dim csb As New SqlConnectionStringBuilder

        csb.DataSource = ServerName
        csb.InitialCatalog = DatabaseName
        csb.UserID = UsuarioDB & "SQL"
        csb.Password = PasswordDB
        csb.IntegratedSecurity = False

        Return csb.ConnectionString
    End Function

    ''' <summary>
    ''' La cadena de conexión a la base de datos
    ''' </summary>
    Private Function CadenaConexionMySQL() As String
        If UsarBaseLocal Then Return "No hay base local de MySQL"

        ConectarMySQL()

        Dim csb As New MySqlConnectionStringBuilder

        csb.Server = ServerName
        csb.Database = DatabaseName
        csb.UserID = UsuarioDB & "My"
        csb.Password = PasswordDB

        Return csb.ConnectionString
    End Function


    ''' <summary>
    ''' Conectar a la base de datos de SQL Server
    ''' </summary>
    Private Sub ConectarSQL()
        If UsarBaseLocal Then
            ServerName = ".\SQLEXPRESS"
        Else
            ServerName = "sql3.servidoreswindows.net"
        End If
    End Sub

    ''' <summary>
    ''' Conectar a la base de datos de MySQL.
    ''' Siempre en remoto.
    ''' </summary>
    Private Sub ConectarMySQL()
        ServerName = "mysql1.servidoreswindows.net"
    End Sub


    ''' <summary>
    ''' Añadir el dato a la base de SQL Server
    ''' </summary>
    Private Function AñadirSQL() As String
        Dim sCon As String = CadenaConexionSQL()
        Dim sel = $"INSERT INTO {Tabla} (Fecha, ConVarChar, ConNVarChar) " &
                  $"VALUES('{DateTime.Now}', '{txtDato.Text}', '{txtDato.Text}')"

        Using con As New SqlConnection(sCon)
            Dim cmd As New SqlCommand(sel, con)

            Try
                con.Open()
                cmd.ExecuteNonQuery()
                con.Close()

                Return ""
            Catch ex As Exception
                Return $"ERROR: {ex.Message}"
            End Try
        End Using
    End Function

    ''' <summary>
    ''' Añadir el dato a la base de datos de MySQL
    ''' </summary>
    Private Function AñadirMySQL() As String
        If UsarBaseLocal Then Return "No hay base local de MySQL"

        Dim sCon = CadenaConexionMySQL()
        ' En MySQL he definido Fecha como varchar(20)
        Dim sel = $"INSERT INTO {Tabla} (Fecha, ConVarChar, ConNVarChar) " &
                  $"VALUES('{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss")}', '{txtDato.Text}', '{txtDato.Text}')"

        Using con As New MySqlConnection(sCon)
            Dim cmd As New MySqlCommand(sel, con)

            Try
                con.Open()
                cmd.ExecuteNonQuery()
                con.Close()

                Return ""
            Catch ex As Exception
                Return $"ERROR: {ex.Message}"
            End Try
        End Using
    End Function

    ''' <summary>
    ''' Mostrar los datos de la base de SQLServer
    ''' </summary>
    Private Function MostrarDatosSQL(ByRef dt As DataTable) As String
        Dim orden = If(chkOrden.Checked, "DESC", "ASC")
        Dim sel = $"SELECT TOP ({MaxFilas}) * FROM {Tabla} ORDER BY Fecha {orden}"

        Dim sCon = CadenaConexionSQL()
        Dim da As SqlDataAdapter
        dt = New DataTable

        Try
            ' Crear un nuevo objeto del tipo DataAdapter
            da = New SqlDataAdapter(sel, sCon)

            ' Llenar la tabla con los datos indicados
            da.Fill(dt)

            Return $"Recuperadas {dt.Rows.Count} filas."
        Catch ex As Exception
            Return $"ERROR: {ex.Message}"
        End Try

    End Function

    ''' <summary>
    ''' Mostrar los datos de MySQL
    ''' </summary>
    Private Function MostrarDatosMySQL(ByRef dt As DataTable) As String
        If UsarBaseLocal Then Return "No hay base local de MySQL"

        Dim orden = If(chkOrden.Checked, "DESC", "ASC")
        ' MySQL no tiene TOP, usar en su lugar LIMIT
        Dim sel = $"SELECT * FROM {Tabla} ORDER BY Fecha {orden} LIMIT {MaxFilas}"

        Dim sCon = CadenaConexionMySQL()
        Dim da As MySqlDataAdapter
        dt = New DataTable

        Try
            ' Crear un nuevo objeto del tipo DataAdapter
            da = New MySqlDataAdapter(sel, sCon)

            ' Llenar la tabla con los datos indicados
            da.Fill(dt)

            Return $"Recuperadas {dt.Rows.Count} filas."
        Catch ex As Exception
            Return $"ERROR: {ex.Message}"
        End Try

    End Function

    Private Sub btnAñadir_Click(sender As Object,
                                e As EventArgs) Handles btnAñadir.Click
        Dim msg = ""

        msg = AñadirSQL() & vbCrLf
        msg &= AñadirMySQL()

        LabelError.Text = msg

        btnRefrescar.PerformClick()
    End Sub

    Private Sub btnRefrescar_Click(sender As Object,
                                   e As EventArgs) Handles btnRefrescar.Click
        Dim dt As DataTable = Nothing
        Dim msg = ""
        lvDatos.Items.Clear()

        Dim i = 5
        Integer.TryParse(txtFilas.Text, i)
        MaxFilas = i

        msg = MostrarDatosSQL(dt) & vbCrLf
        asignarDatos("SQL", dt)

        Dim lvi = lvDatos.Items.Add("---")
        lvi.SubItems.Add("---")
        lvi.SubItems.Add("---")
        lvi.SubItems.Add("---")

        dt = Nothing
        msg &= MostrarDatosMySQL(dt)
        asignarDatos("MySQL", dt)

        LabelError.Text = msg
    End Sub

    Private Sub asignarDatos(base As String, dt As DataTable)
        If dt Is Nothing Then Return

        For Each r As DataRow In dt.Rows
            Dim lvi = lvDatos.Items.Add(base)
            lvi.SubItems.Add(r("Fecha").ToString)
            lvi.SubItems.Add(r("ConVarChar").ToString)
            lvi.SubItems.Add(r("ConNVarChar").ToString)
        Next

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        inicializando = False
    End Sub

    Private Sub ChkUsarBaseLocal_CheckedChanged(sender As Object, e As EventArgs) Handles chkUsarBaseLocal.CheckedChanged
        If inicializando Then Return

        UsarBaseLocal = chkUsarBaseLocal.Checked
    End Sub

End Class

El código para C#

//-----------------------------------------------------------------------------
// Prueba de los tipos de SQL VarChar y NVarChar                    (21/Mar/19)
// Usando base de SQL Server y MySQL
//
//
// (c) Guillermo (elGuille) Som, 2019
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Data.SqlClient;
// Versión de mysql.data.dll: Connector/Net 6.0.3.0
using MySql.Data.MySqlClient;

namespace VarChar_y_NVarChar_cs
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private bool inicializando = true;

        /// <summary>
        /// Para las primeras pruebas uso una base local
        /// </summary>
        private bool UsarBaseLocal = true;

        private string ServerName = @".\SQLEXPRESS";
        private string DatabaseName = "PruebaVarChar";
        private string UsuarioDB = "elGuille_info";
        private string PasswordDB = "VarChar_19";

        private string Tabla = "VarCharElGuille";
        // Campos: Fecha, ConVarChar varchar(50), ConNVarChar nvarchar(50)
        // en MySQL no hay NVARCHAR y uso TEXT(50)

        private int MaxFilas = 5;

        /// <summary>
        /// La cadena de conexión a la base de datos
        /// </summary>
        private string CadenaConexionSQL()
        {
            ConectarSQL();

            var csb = new SqlConnectionStringBuilder();

            csb.DataSource = ServerName;
            csb.InitialCatalog = DatabaseName;
            csb.UserID = UsuarioDB + "SQL";
            csb.Password = PasswordDB;
            csb.IntegratedSecurity = false;

            return csb.ConnectionString;
        }

        /// <summary>
        /// La cadena de conexión a la base de datos
        /// </summary>
        private string CadenaConexionMySQL()
        {
            if (UsarBaseLocal)
                return "No hay base local de MySQL";

            ConectarMySQL();

            var csb = new MySqlConnectionStringBuilder();

            csb.Server = ServerName;
            csb.Database = DatabaseName;
            csb.UserID = UsuarioDB + "My";
            csb.Password = PasswordDB;

            return csb.ConnectionString;
        }


        /// <summary>
        /// Conectar a la base de datos de SQL Server
        /// </summary>
        private void ConectarSQL()
        {
            if (UsarBaseLocal)
                ServerName = @".\SQLEXPRESS";
            else
                ServerName = "sql3.servidoreswindows.net";
        }

        /// <summary>
        /// Conectar a la base de datos de MySQL.
        /// Siempre en remoto.
        /// </summary>
        private void ConectarMySQL()
        {
            ServerName = "mysql1.servidoreswindows.net";
        }


        /// <summary>
        /// Añadir el dato a la base de SQL Server
        /// </summary>
        private string AñadirSQL()
        {
            string sCon = CadenaConexionSQL();
            var sel = $"INSERT INTO {Tabla} (Fecha, ConVarChar, ConNVarChar) " + 
                      $"VALUES('{DateTime.Now}', '{txtDato.Text}', '{txtDato.Text}')";

            using (var con = new SqlConnection(sCon))
            {
                var cmd = new SqlCommand(sel, con);

                try
                {
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();

                    return "";
                }
                catch (Exception ex)
                {
                    return $"ERROR: {ex.Message}";
                }
            }
        }

        /// <summary>
        /// Añadir el dato a la base de datos de MySQL
        /// </summary>
        private string AñadirMySQL()
        {
            if (UsarBaseLocal)
                return "No hay base local de MySQL";

            var sCon = CadenaConexionMySQL();
            // En MySQL he definido Fecha como varchar(20)
            var sel = $"INSERT INTO {Tabla} (Fecha, ConVarChar, ConNVarChar) " + 
                      $"VALUES('{DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss")}', '{txtDato.Text}', '{txtDato.Text}')";

            using (var con = new MySqlConnection(sCon))
            {
                var cmd = new MySqlCommand(sel, con);

                try
                {
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();

                    return "";
                }
                catch (Exception ex)
                {
                    return $"ERROR: {ex.Message}";
                }
            }
        }

        /// <summary>
        /// Mostrar los datos de la base de SQLServer
        /// </summary>
        private string MostrarDatosSQL(ref DataTable dt)
        {
            var orden = chkOrden.Checked ? "DESC" : "ASC";
            var sel = $"SELECT TOP ({MaxFilas}) * FROM {Tabla} ORDER BY Fecha {orden}";

            var sCon = CadenaConexionSQL();
            SqlDataAdapter da;
            dt = new DataTable();

            try
            {
                // Crear un nuevo objeto del tipo DataAdapter
                da = new SqlDataAdapter(sel, sCon);

                // Llenar la tabla con los datos indicados
                da.Fill(dt);

                return $"Recuperadas {dt.Rows.Count} filas.";
            }
            catch (Exception ex)
            {
                return $"ERROR: {ex.Message}";
            }
        }

        /// <summary>
        /// Mostrar los datos de MySQL
        /// </summary>
        private string MostrarDatosMySQL(ref DataTable dt)
        {
            if (UsarBaseLocal)
                return "No hay base local de MySQL";

            var orden = chkOrden.Checked ? "DESC" : "ASC";
            // MySQL no tiene TOP, usar en su lugar LIMIT
            var sel = $"SELECT * FROM {Tabla} ORDER BY Fecha {orden} LIMIT {MaxFilas}";

            var sCon = CadenaConexionMySQL();
            MySqlDataAdapter da;
            dt = new DataTable();

            try
            {
                // Crear un nuevo objeto del tipo DataAdapter
                da = new MySqlDataAdapter(sel, sCon);

                // Llenar la tabla con los datos indicados
                da.Fill(dt);

                return $"Recuperadas {dt.Rows.Count} filas.";
            }
            catch (Exception ex)
            {
                return $"ERROR: {ex.Message}";
            }
        }

        private void BtnAñadir_Click(object sender, EventArgs e)
        {
            var msg = "";

            msg = AñadirSQL() + "\n";
            msg += AñadirMySQL();

            LabelError.Text = msg;

            btnRefrescar.PerformClick();
        }

        private void BtnRefrescar_Click(object sender, EventArgs e)
        {
            DataTable dt = null;
            var msg = "";
            lvDatos.Items.Clear();

            var i = 5;
            int.TryParse(txtFilas.Text, out i);
            MaxFilas = i;

            msg = MostrarDatosSQL(ref dt) + "\n";
            asignarDatos("SQL", dt);

            var lvi = lvDatos.Items.Add("---");
            lvi.SubItems.Add("---");
            lvi.SubItems.Add("---");
            lvi.SubItems.Add("---");

            dt = null;
            msg += MostrarDatosMySQL(ref dt);
            asignarDatos("MySQL", dt);

            LabelError.Text = msg;
        }

        private void asignarDatos(string @base, DataTable dt)
        {
            if (dt == null) return;

            foreach (DataRow r in dt.Rows)
            {
                var lvi = lvDatos.Items.Add(@base);
                lvi.SubItems.Add(r["Fecha"].ToString());
                lvi.SubItems.Add(r["ConVarChar"].ToString());
                lvi.SubItems.Add(r["ConNVarChar"].ToString());
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            inicializando = false;
        }

        private void ChkUsarBaseLocal_CheckedChanged(object sender, EventArgs e)
        {
            if (inicializando) return;

            UsarBaseLocal = chkUsarBaseLocal.Checked;
        }
    }
}

Y esto es todo… espero que te sea de utilidad.

Nos vemos.
Guillermo

El código completo del ejemplo
(solución para Visual Studio usando .NET 4.7.2)

El ZIP con el código completo (una solución de Visual Studio 2019 Preview con los proyectos de Visual Basic y C# además de la DLL de MySQL con la referencia a la copia dentro del directorio de la solución.

El zip: VarChar_y_NVarChar_20190321.zip (147 KB)

MD5 Checksum: 888346C11622183F6A39FE5FBA4339D3

Nota:

Aquí tienes el enlace para la descarga del ZIP que me descargué con el conector de MySQL para .NET versión 6.0.3 (mysql-connector-net-6.0.3-noinstall.zip) el tamaño es 1.64MB y el MD5 Checksum es: 57BB7F42645665D5A616A3484041F0C0.

Cuidado con las horas de las fechas en las consultas de SQL

Pues eso… que esto de las fechas en las consultas es como el cuento de nunca acabar… al menos para mí, jeje.

Lo que me ha pasado esta vez es que he estado usando fechas en una consulta y, como ya comenté hace años, la mejor forma de pasarlas a la consulta de SQL es usando parámetros, hasta aquí todo bien.

' Crear un nuevo objeto del tipo DataAdapter
da = New SqlDataAdapter(sel, sCon)
da.SelectCommand.Parameters.AddWithValue("@fecha1", fecha1)
da.SelectCommand.Parameters.AddWithValue("@fecha2", fecha2)

En esta ocasión, las fechas las he pasado como argumento a un método normal con el tipo de datos de las fechas (DateTime o Date en VB). Aclaro esto porque cuando se convierte un objeto del tipo fecha a una cadena (que es lo que supongo que hace el SQL cuando va a trabajar con la fecha) ese objeto del tipo fecha se convierte en una fecha y una hora (ver la figura 1).

fechas_sql_02jun2016_peq
Figura 1. Los objetos de tipo Date (DateTime) contienen la fecha y la hora.

En este ejemplo, el valor pasado en el primer argumento tiene la fecha y la hora a las 12 de la madrugada, es decir a las 00:00:00 que es lo que ocurre cuando conviertes una fecha de cadena a tipo DateTime.

Pero si la fecha la obtienes, por ejemplo, de un DateTimePicker o simplemente usando DateTime.Now que obtiene la fecha (y hora) actual. En el caso de que ese valor se obtenga a la hora en que escribo esto, mostrará un valor de fecha 2 de junio de 2016 y la hora 13 (01 PM) y 24 minutos con nosecuantos segundos (ver la figura 2).

fechas_sql_02jun2016_2
Figura 2. Now devuelve la fecha y hora actual completa.

En este caso la propiedad Now del objeto fecha devuelve la fecha y la hora actual, y lo que hace la función esa que muestro en la figura 2 (NowDate) es devolver solo la fecha, sin hora… aunque la hora siempre está, pero si no se indica será 00:00:00 (media noche).

Bueno, espero que te pueda servir de ayuda en casos como el que me pasó a mí, que aún habiendo un dato (de la misma fecha en la que hacía la comprobación) no me lo mostraba porque la hora era (por ejemplo las 9 de la noche) y esa fecha no era igual (o menor) que la que estaba guardada en la base de datos (que era el mismo día, pero a las cero horas), en fin…

Nos vemos.
Guillermo

Cuidado con las horas de las fechas en las consultas de SQL

Pues eso… que esto de las fechas en las consultas es como el cuento de nunca acabar… al menos para mí, jeje.

Lo que me ha pasado esta vez es que he estado usando fechas en una consulta y, como ya comenté hace años, la mejor forma de pasarlas a la consulta de SQL es usando parámetros, hasta aquí todo bien.

' Crear un nuevo objeto del tipo DataAdapter
da = New SqlDataAdapter(sel, sCon)
da.SelectCommand.Parameters.AddWithValue("@fecha1", fecha1)
da.SelectCommand.Parameters.AddWithValue("@fecha2", fecha2)

En esta ocasión, las fechas las he pasado como argumento a un método normal con el tipo de datos de las fechas (DateTime o Date en VB). Aclaro esto porque cuando se convierte un objeto del tipo fecha a una cadena (que es lo que supongo que hace el SQL cuando va a trabajar con la fecha) ese objeto del tipo fecha se convierte en una fecha y una hora (ver la figura 1).

fechas_sql_02jun2016_peq
Figura 1. Los objetos de tipo Date (DateTime) contienen la fecha y la hora.

En este ejemplo, el valor pasado en el primer argumento tiene la fecha y la hora a las 12 de la madrugada, es decir a las 00:00:00 que es lo que ocurre cuando conviertes una fecha de cadena a tipo DateTime.

Pero si la fecha la obtienes, por ejemplo, de un DateTimePicker o simplemente usando DateTime.Now que obtiene la fecha (y hora) actual. En el caso de que ese valor se obtenga a la hora en que escribo esto, mostrará un valor de fecha 2 de junio de 2016 y la hora 13 (01 PM) y 24 minutos con nosecuantos segundos (ver la figura 2).

fechas_sql_02jun2016_2
Figura 2. Now devuelve la fecha y hora actual completa.

En este caso la propiedad Now del objeto fecha devuelve la fecha y la hora actual, y lo que hace la función esa que muestro en la figura 2 (NowDate) es devolver solo la fecha, sin hora… aunque la hora siempre está, pero si no se indica será 00:00:00 (media noche).

Bueno, espero que te pueda servir de ayuda en casos como el que me pasó a mí, que aún habiendo un dato (de la misma fecha en la que hacía la comprobación) no me lo mostraba porque la hora era (por ejemplo las 9 de la noche) y esa fecha no era igual (o menor) que la que estaba guardada en la base de datos (que era el mismo día, pero a las cero horas), en fin…

Nos vemos.
Guillermo

Cuidado con las horas de las fechas en las consultas de SQL

 

Pues eso… que esto de las fechas en las consultas es como el cuento de nunca acabar… al menos para mí, jeje.

Lo que me ha pasado esta vez es que he estado usando fechas en una consulta y, como ya comenté hace años, la mejor forma de pasarlas a la consulta de SQL es usando parámetros, hasta aquí todo bien.

 

' Crear un nuevo objeto del tipo DataAdapter
da = New SqlDataAdapter(sel, sCon)
da.SelectCommand.Parameters.AddWithValue("@fecha1", fecha1)
da.SelectCommand.Parameters.AddWithValue("@fecha2", fecha2)

 

En esta ocasión, las fechas las he pasado como argumento a un método normal con el tipo de datos de las fechas (DateTime o Date en VB). Aclaro esto porque cuando se convierte un objeto del tipo fecha a una cadena (que es lo que supongo que hace el SQL cuando va a trabajar con la fecha) ese objeto del tipo fecha se convierte en una fecha y una hora (ver la figura 1).

fechas_sql_02jun2016_peq
Figura 1. Los objetos de tipo Date (DateTime) contienen la fecha y la hora.

En este ejemplo, el valor pasado en el primer argumento tiene la fecha y la hora a las 12 de la madrugada, es decir a las 00:00:00 que es lo que ocurre cuando conviertes una fecha de cadena a tipo DateTime.

Pero si la fecha la obtienes, por ejemplo, de un DateTimePicker o simplemente usando DateTime.Now que obtiene la fecha (y hora) actual. En el caso de que ese valor se obtenga a la hora en que escribo esto, mostrará un valor de fecha 2 de junio de 2016 y la hora 13 (01 PM) y 24 minutos con nosecuantos segundos (ver la figura 2).

fechas_sql_02jun2016_2
Figura 2. Now devuelve la fecha y hora actual completa.

En este caso la propiedad Now del objeto fecha devuelve la fecha y la hora actual, y lo que hace la función esa que muestro en la figura 2 (NowDate) es devolver solo la fecha, sin hora… aunque la hora siempre está, pero si no se indica será 00:00:00 (media noche).

 

Bueno, espero que te pueda servir de ayuda en casos como el que me pasó a mí, que aún habiendo un dato (de la misma fecha en la que hacía la comprobación) no me lo mostraba porque la hora era (por ejemplo las 9 de la noche) y esa fecha no era igual (o menor) que la que estaba guardada en la base de datos (que era el mismo día, pero a las cero horas), en fin…

Nos vemos.
Guillermo

ejemplo de ExecuteScalar para leer una columna de una tabla

 

Pues eso… que esto seguro que lo tengo mil veces publicado en mi sitio, pero hoy lo he ido a buscar, y no lo he encontrado de forma concreta, así que… aquí está para que "yo" lo encuentre… jejeje

¿Por qué buscaba esto?

El caso es el siguiente: necesitaba saber el ID (u otro campo) de una tabla de una base de datos de SQL Server Express 2014 (el tipo de base de datos es indiferente siempre que tenga el método que te comento) haciendo una consulta, concretamente usando LIKE en la propia cadena de selección o consulta.

La consulta es la siguiente:

String.Format( "SELECT ID FROM Clientes WHERE Nombre LIKE '%{0}%' AND Apellidos LIKE '%{1}%'",

nombre, apellidos)

No indico la forma de asignar esa cadena para que uses VB o C#, en el primer caso tendrías que indicar Dim sel = y en el segundo var sel =

A continuación creamos un objeto del tipo Connection y otro del tipo Command y hacemos una llamada al método ExecuteScalar y el valor que devuelva será (en este caso concreto) el ID que estamos buscando o CERO si no lo ha encontrado.

Simplificando (sin tratamiento de error y esas cosas), si el acceso a la base de datos es de SQL Server (en este ejemplo en una instancia de SQLEXPRESS) y usamos las clases definidas en System.Data.SqlClient, el código sería algo así:

Visual Basic:

Public Shared Function BuscarCliente2(nombre As String, apellidos As String) As Integer
    Dim elID As Integer = 0

    Dim sel =
        String.Format(
            "SELECT ID FROM Clientes WHERE Nombre LIKE '%{0}%' AND Apellidos LIKE '%{1}%'",
            nombre, apellidos)

    Dim sCon = ".\sqlexpress;Initial Catalog=LaBaseDeDatos;Integrated Security=True"

    Using con As New SqlConnection(sCon)
        Dim cmd As New SqlCommand(sel, con)

        con.Open()

        elID = CInt(cmd.ExecuteScalar())

        con.Close()
    End Using

    Return elID
End Function

 

C#:

public static int BuscarCliente2(string nombre, string apellidos)
{
    int elID = 0;

    var sel =
        String.Format(
            "SELECT ID FROM Clientes WHERE Nombre LIKE '%{0}%' AND Apellidos LIKE '%{1}%'",
            nombre, apellidos);

    var sCon = @".\sqlexpress;Initial Catalog=LaBaseDeDatos;Integrated Security=True";

    using (SqlConnection con = new SqlConnection(sCon))
    {
        SqlCommand cmd = new SqlCommand(sel, con);

        con.Open();

        elID = Convert.ToInt32(cmd.ExecuteScalar());

        con.Close();
    }

    return elID;
}

 

Y esto es todo amigos… 🙂

 

Nos vemos.

Guillermo

probar varias cadenas de conexión si una da error, y no morir en el intento

 

Pues eso… que estaba modificando/probando la aplicación esa que en su día te comenté para acceder a los ficheros de FoxPro (o dBase) con la extensión DBF y resulta que me dio error al conectar a la base de datos, concretamente este:

ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

Así que… me fui a ver mi artículo (Acceso a ficheros dBase (.dbf) desde Visual Basic .NET y C#) y usé otra cadena de conexión (todo esto después de probar a instalar los drivers de VFP -que por cierto me equivoqué e instalé y los de OLEDB en vez de los de ODBC porque no encontré los drivers de este último… y ¡me lié! po zí…  pero bueno, ese es otro tema… jum!).
La cuestión es que tuve que desinstalar los drivers de OLEDB ya que la cadena de conexión y el tipo de datos que quería usar eran los de ODBC.

Nota aclaratoria del 23/Abr/2015 11:15
Aparte de agregar un nuevo comentario al párrafo anterior, quiero aclararte que:
Busqué los drivers de ODBC (que son los que yo quería utilizar) y por error me bajé los de OLEDB y después de instalarlos y probar “con la conexión ODBC” de que no funcionaba -lógico, no son los adecuados- desinstalé los drivers de OLEDB y usé una cadena de conexión diferente que en mi equipo sí funcionaba (sin los drivers de VFP), pero no en el equipo de mi amigo que aún tenía los drivers de VFP que en su día instaló…

Para tu información la cadena que inicialmente estaba usando (y la que funciona en el equipo de mi colega) es esta:

"Driver={Microsoft Visual FoxPro Driver};
SourceType=DBF;
SourceDB=" & sBase & ";"

Y la otra que probé y a mi sí me funcionó es esta otra:

"Driver={Microsoft dBASE Driver (*.dbf)};
DriverID=277;
Dbq=" & sBase & ";"

La cuestión es que la de Visual FoxPro Driver a mi no me iba y la de dBASE driver no le iba a mi colega Manolo (le da el error de la figura 1).

error dBASE en equipo Manolo

Figura 1. Error del controlador/driver dBASE

Así que… tenía que hacer algo para usar uno en un equipo y otro en el otro… y antes de ponerme a saber el nombre del equipo y demás, me dije… jum! esta vez voy a probar primero lo más simple y después ya veré si me tengo que complicar la vida con otras cosas.

Y lo más simple para mi es: ¡probar si puede conectar con una cadena de conexión y si no puede, entonces probar otra! y…

(Ahora, al escribir esto último me recuerda mis tiempos de programador de Quick BASIC y el uso y "mal uso" de ON ERROR RESUME NEXT o lo que es lo mismo: si se produce un error que continúe girando el mundo… ¡hasta que se pare! jaja… en fin…)

Y eso he hecho y eso es lo que me funciona, mi colega aún no lo habrá probado, pero seguro que a él también le funciona; así que… si funciona… ¡todos contentos! 🙂

(y sobre todo, él puede seguir trabajando, yo no, pero él sí jeje)

Y este es el código que he usado (por ahora en Visual Basic .NET ya que mis proyectos los suelo hacer siempre para Visual Basic -salvo excepciones).

 

El código de la función LeerBases(path) para Visual Basic .NET

Public Shared Function LeerBases(ByVal dirDBF As DirectoryInfo) As DataSet
    Datos = New DataSet

    Dim sBase As String = dirDBF.FullName
    Dim sConn As String

    Dim ficsDbf() As FileInfo = dirDBF.GetFiles("*.dbf")
    If ficsDbf.Length = 0 Then Return Datos

    ' Utilizar varias conexiones y probar con las siguientes si da error (14/Abr/15)
    Dim cadenasConexión() As String = {"Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=" & sBase & ";",
                                       "Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=" & sBase & ";"}

    Dim intentosConexion As Integer = 0
    Dim hayError As Boolean = False
    Dim mensajeError As String = ""

    Do
        sConn = cadenasConexión(intentosConexion)

        Using dbConn As New System.Data.Odbc.OdbcConnection(sConn)
            Try
                dbConn.Open()

                For Each fi As FileInfo In ficsDbf
                    Dim sSelect As String = "SELECT * FROM " & fi.Name

                    Dim da As New System.Data.Odbc.OdbcDataAdapter(sSelect, dbConn)
                    Dim dt As New DataTable

                    da.Fill(dt)
                    If dt.Rows.Count > 0 Then
                        Datos.Tables.Add(dt)
                    End If
                Next

                dbConn.Close()

                hayError = False

                ' Salir del bucle,
                ' no sea que haya más opciones de conectar y no es plan...
                Exit Do

            Catch ex As Exception
                mensajeError = _
                    "Error al abrir la base de datos" & vbCrLf &
                    ex.Message & vbCrLf &
                    "Usando: '" & cadenasConexión(intentosConexion) & "'"
                hayError = True

                ' Este es el mensaje de error que me muestra:
                ' ERROR [IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
            End Try
        End Using

        intentosConexion += 1
    Loop While intentosConexion < cadenasConexión.Length

    If hayError Then
        System.Windows.Forms.MessageBox.Show(mensajeError,
                                             "Error al conectar a los datos de DBF",
                                             System.Windows.Forms.MessageBoxButtons.OK,
                                             System.Windows.Forms.MessageBoxIcon.Exclamation)
    End If

    Return Datos
End Function


 

Y esto es todo amigos… 🙂

Espero que te sea de utilidad y que si así lo es, me invites a un té o un refresco… y como va a ser complicado que nos veamos para esa invitación (y no es plan de esperar a que eso ocurra en otra vida), puedes invitarme usando el botón de Donar ese que tengo en mi blog, allí, arriba a la derecha o en mi sitio, sí, ese que está allí arriba, donde dice eso de Donativo para el sitio de elGuille.

Gracias.

 

Nos vemos.

Guillermo

Este artículo también está publicado en mi sitio:

http://www.elguille.info/NET/ADONET/probar-varias-cadenas-de-conexion-si-una-da-error-y-no-morir-en-el-intento.aspx

( En realidad obtiene el contenido desde aquí, de mi blog 🙂 )

como conectar a una base de datos de MySQL en un servidor Web desde .NET

 

Pues eso… hace unos días he estado haciendo una pequeña aplicación para acceder a una base de datos de MySQL creada en un servidor web de Domitienda y voy a aprovechar para comentarte las cosillas que he hecho (como conectar a una BBDD de MySQL, enviar emails, obtener datos de tres tablas diferentes pero que había que relacionar para sacar lo que interesaba, etc.) y la primera fue lo más importante: Conectar con una base de datos de MySQL con Visual Basic .NET (o .NET en general).
Y esto es lo que te voy a contar en este "artículo" de hoy lunes 13 de abril de 2015.

Los requisitos

Lo primero que deberías hacer es descargarte la DLL (librería/biblioteca) de MySQL para usar con Visual Studio, bueno, en realidad lo que yo me iba a bajar el Connector .NET, concretamente la versión 6.9.6 porque decía que la versión 6.7 el Connector/Net no incluye el "MySQL for Visual Studio integration", así que ni me puse a "investigar" a qué se refería, por tanto me bajé el MySQL for Visual Studio, concretamente la versión web community 5.6.23.0 (a la hora de escribir esto está la versión 5.6.24.0).

Nota:
El descargar la versión "web community" es porque tenía conexión a internet y así solo tenía que descargar 1.6MB frente a los 286,7MB de la versión off-line.

Es un MSI installer y te da un montón (o dos o tres o cuatro, pal caso es lo mismo) de opciones, pero solo usé la del Connector o lo que pusiera en las opciones de instalación.

 

Añadir la referencia de MySql.Data al proyecto

Una vez instalado, en el proyecto desde el que quieras acceder a la base de datos de MySQL le agregas la referencia correspondiente.
En mi caso usé la versión 4.5 ya que el proyecto también usaba el .NET Framework 4.5 (ver la figura 1).

MySqlData referencia
Figura 1. Referencia al ensamblado de MySql.Data versión 6.9.5

Y una vez que hemos agregado la referencia al ensamblado MySql.Data ya podemos acceder a las clases de conexión y demás, que están en el espacio de nombres MySql.Data.MySqlClient.

Y el resto… como de costumbre… pero no te preocupes te voy a poner el código (primero para VB y después para C#) de cómo usar la conexión y acceder a una tabla y demás, pero eso será… ¡ma-ña-na! 🙂

Bueno, vale, al menos te pondré el código de cómo conectar a la base de datos.

 

Conectar a la base de datos de MySQL desde Visual Basic .NET

Yo suelo usar un método en una clase con métodos compartidos (en VB puedes usar un módulo, pero yo uso una clase para después convertir fácilmente el código a C#), el método es una función llamada CadenaConexion que devuelve una cadena con la cadena de conexión generada por la clase ConnectionStringBuilder, en realidad la clase se llama MySqlConnectionStringBuilder, pero si has usado conexión a SQL Server sabrás que en ese caso el nombre es SqlConnectionStringBuilder.

Para poder acceder a las clases de MySql.Data debes añadir una importación de espacios de nombres a MySql.Data.MySqlClient:

' Para Visual Basic:
Imports MySql.Data.MySqlClient

// Para C#:
using MySql.Data.MySqlClient;

Y esta es la definición del método que está en una clase (class) de VB y por eso el método lo he definido como Shared (static en C#) para que lo puedas usar simplemente anteponiendo el nombre de la clase y sin necesidad de crear nuevas instancias ni nada de eso:

El código del método CadenaConexion para Visual Basic:

''' <summary>
''' La cadena de conexión a la base de datos
''' </summary>
Public Shared Function CadenaConexion() As String
    Dim csb As New MySqlConnectionStringBuilder
    csb.Server = "mysql3.servidoreswindows.net"
    csb.Database = "nombre_Base_Datos"
    csb.UserID = "nombre_usuario_de_la_base"
    csb.Password = "la_clave_del_usuario_de_la_base"
    csb.IntegratedSecurity = False

    Return csb.ConnectionString
End Function

El método CadenaConexion para C#:

/// <summary>
/// La cadena de conexión a la base de datos
/// </summary>
public static string CadenaConexion()
{
    MySqlConnectionStringBuilder csb = new MySqlConnectionStringBuilder();
    csb.Server = "mysql3.servidoreswindows.net";
    csb.Database = "nombre_Base_Datos";
    csb.UserID = "nombre_usuario_de_la_base";
    csb.Password = "la_clave_del_usuario_de_la_base";
    csb.IntegratedSecurity = false;

    return csb.ConnectionString;
}

 

Y esto es todo por hoy… mañana (seguramente)… más… 😉

 

Nos vemos.

Guillermo

Este artículo también está publicado en mi sitio:

http://www.elguille.info/NET/ADONET/MySQL_CadenaConexion.aspx

( En realidad obtiene el contenido desde aquí, de mi blog 🙂 )