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