Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Microsoft SQL proporciona varios tipos de cadenas que el controlador mssql-python mapea a objetos Pythonstr. La decisión clave es si usar varchar (no Unicode) o nvarchar (Unicode):
- Úsalo
nvarcharcuando tus datos puedan contener caracteres fuera de ASCII, como nombres, direcciones o contenido generado por usuarios en cualquier idioma. - Úsalo
varcharcuando los datos son estrictamente ASCII (códigos, identificadores, direcciones de correo electrónico) y quieres ahorrar almacenamiento.varcharusa 1 byte por carácter;nvarcharUsa 2 bytes por carácter.
| Tipo de SQL | Unicode | Longitud máxima | Tipo de Python |
|---|---|---|---|
char(n) |
No | 8,000 | str |
varchar(n) |
No | 8,000 | str |
varchar(max) |
No | 2 GB | str |
nchar(n) |
Sí | 4,000 | str |
nvarchar(n) |
Sí | 4,000 | str |
nvarchar(max) |
Sí | 2 GB | str |
text |
No | 2 GB (en desuso) | str |
ntext |
Sí | 2 GB (en desuso) | str |
Operaciones básicas de cadenas
El controlador asigna todos los tipos de cadenas SQL de Microsoft a objetos Pythonstr.
Insertar y recuperar cuerdas
Utiliza consultas parametrizadas para insertar y obtener datos de cadenas de la base de datos de forma segura.
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
# Create temp table for demo
cursor.execute("""
CREATE TABLE #StringDemo (
ID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(100),
Email NVARCHAR(200)
)
""")
# Insert string data
cursor.execute(
"INSERT INTO #StringDemo (Name, Email) VALUES (%(name)s, %(email)s)",
{"name": "Alice Smith", "email": "alice@example.com"}
)
conn.commit()
# Retrieve string data
cursor.execute("SELECT Name, Email FROM #StringDemo WHERE ID = 1")
row = cursor.fetchone()
print(row.Name) # 'Alice Smith'
print(row.Email) # 'alice@example.com'
Cadenas con caracteres especiales
Maneja comillas, corchetes angulares y otros caracteres especiales en cadenas usando consultas parametrizadas.
# Quotes and special characters handled automatically
cursor.execute("""
CREATE TABLE #Notes (
ID INT IDENTITY(1,1) PRIMARY KEY,
Title NVARCHAR(200),
Content NVARCHAR(MAX)
)
""")
cursor.execute(
"INSERT INTO #Notes (Title, Content) VALUES (%(title)s, %(content)s)",
{
"title": "O'Brien's Report",
"content": 'Contains "quotes" and special chars: <>&'
}
)
conn.commit()
Compatibilidad con Unicode
Usa columnas nvarchar y Python str para almacenar y recuperar texto en cualquier lenguaje.
Almacenar texto Unicode
Inserta contenido Unicode pasando cadenas de Python a consultas parametrizadas; el controlador las codifica como UTF-16LE para columnas nvarchar.
# International characters - use nvarchar columns
cursor.execute("""
CREATE TABLE #Messages (
ID INT IDENTITY(1,1) PRIMARY KEY,
Content NVARCHAR(MAX)
)
""")
cursor.execute("""
INSERT INTO #Messages (Content) VALUES (%(msg)s)
""", {"msg": "Hello 你好 مرحبا שלום 🎉"})
cursor.execute("SELECT Content FROM #Messages WHERE ID = 1")
row = cursor.fetchone()
print(row.Content) # 'Hello 你好 مرحبا שלום 🎉'
Unicode en diferentes escrituras
Admita varios idiomas y sistemas de escritura en una sola tabla mediante columnas nvarchar e inserciones masivas.
messages = [
{"lang": "English", "text": "Hello, World!"},
{"lang": "Chinese", "text": "你好,世界!"},
{"lang": "Japanese", "text": "こんにちは世界!"},
{"lang": "Korean", "text": "안녕하세요, 세상!"},
{"lang": "Arabic", "text": "مرحبا بالعالم!"},
{"lang": "Hebrew", "text": "שלום עולם!"},
{"lang": "Russian", "text": "Привет мир!"},
{"lang": "Greek", "text": "Γειά σου Κόσμε!"},
{"lang": "Emoji", "text": "👋🌍✨🎉"},
]
cursor.execute("""
CREATE TABLE #Greetings (
ID INT IDENTITY(1,1) PRIMARY KEY,
Language NVARCHAR(50),
Message NVARCHAR(200)
)
""")
cursor.executemany("""
INSERT INTO #Greetings (Language, Message) VALUES (%(lang)s, %(text)s)
""", messages)
conn.commit()
Asegúrese de que las columnas sean de tipo nvarchar para Unicode
Define siempre las columnas como nvarchar en lugar de varchar cuando tus datos puedan contener caracteres no ASCII.
-- For Unicode data, always use nvarchar, not varchar
CREATE TABLE #UnicodeDemo (
ID INT IDENTITY PRIMARY KEY,
Name NVARCHAR(100), -- Supports Unicode
Description NVARCHAR(MAX) -- Supports large Unicode text
);
Consideraciones sobre la longitud de las cuerdas
Elige entre tipos de longitud fija y variable según la consistencia de tus datos.
Longitud fija frente a variable
Microsoft SQL rellena los valores con espacios finales hasta la longitud declarada. Este relleno desperdicia almacenamiento para datos de longitud variable, pero puede mejorar el rendimiento para columnas de ancho fijo, como códigos de país. Use varchar(n) para la mayoría de las columnas de texto.
El siguiente ejemplo muestra la diferencia en cómo las columnas rellenadas frente a las no acolchadas gestionan la recuperación de datos:
# char(6) pads to fixed length
cursor.execute(
"SELECT StateProvinceCode FROM Person.StateProvince WHERE StateProvinceID = 1"
) # nchar(6) column
row = cursor.fetchone()
print(repr(row.StateProvinceCode)) # 'AB ' - right-padded with spaces
# nvarchar stores actual length
cursor.execute(
"SELECT Name FROM Person.StateProvince WHERE StateProvinceID = 1"
) # nvarchar column
row = cursor.fetchone()
print(repr(row.Name)) # 'Alberta' - no padding
Gestionar espacios finales
Al recuperar datos de columnas de caracteres de longitud fija, úsalo rstrip() para eliminar los espacios de relleno añadidos por Microsoft SQL Server.
# Strip trailing spaces from char columns
cursor.execute("SELECT ProductNumber FROM Production.Product")
for row in cursor:
code = row.ProductNumber.rstrip() # Remove trailing spaces
print(f"Code: '{code}'")
Cadenas grandes (tipos MAX)
Los nvarchar(max) tipos y varchar(max) soportan cadenas de hasta 2 GB, ideales para almacenar documentos de texto grandes, contenido JSON o XML.
# Large text content
large_content = "x" * 100000 # 100K characters
cursor.execute("""
CREATE TABLE #Documents (
ID INT IDENTITY(1,1) PRIMARY KEY,
Content NVARCHAR(MAX)
)
""")
cursor.execute("""
INSERT INTO #Documents (Content) VALUES (%(content)s)
""", {"content": large_content})
cursor.execute("SELECT Content FROM #Documents WHERE ID = 1")
row = cursor.fetchone()
print(len(row.Content)) # 100000
Comparación y colación de cadenas
El comportamiento de la comparación de cadenas en Microsoft SQL depende de la intercalación establecida en la base de datos o en la columna.
Distinción entre mayúsculas y minúsculas
La comparación de cadenas SQL de Microsoft depende de la recopilación. Por defecto, la mayoría de las bases de datos utilizan una intercalación que no distingue entre mayúsculas y minúsculas, pero puedes anular este comportamiento con la cláusula COLLATE.
# Case-insensitive collation (default for many databases)
cursor.execute("SELECT * FROM Person.Person WHERE LastName = %(name)s", {"name": "smith"})
# Might match 'Smith', 'SMITH', 'smith' depending on collation
# For case-sensitive comparison
cursor.execute("""
SELECT * FROM Person.Person
WHERE LastName COLLATE Latin1_General_CS_AS = %(name)s
""", {"name": "Smith"})
Comparación de patrones con LIKE
Use el operador LIKE con caracteres comodín para buscar patrones de texto; escape los caracteres especiales con notación entre corchetes para que coincidan con caracteres literales.
# Wildcard searches
search_term = "Road"
cursor.execute("""
SELECT Name FROM Production.Product WHERE Name LIKE %(pattern)s
""", {"pattern": f"%{search_term}%"})
# Escape special characters in search
def escape_like(value: str) -> str:
"""Escape LIKE wildcards in search value."""
return value.replace("[", "[[]").replace("%", "[%]").replace("_", "[_]")
search = "100%"
cursor.execute("""
SELECT Name FROM Production.Product WHERE Name LIKE %(pattern)s
""", {"pattern": f"%{escape_like(search)}%"})
Consideraciones de codificación
El comportamiento de codificación depende del tipo de columna SQL de Microsoft y de la clasificación de la fuente.
Supuestos de codificación y valores predeterminados de Unicode
El mssql-python controlador gestiona la codificación automáticamente según el tipo de columna SQL de Microsoft. Por defecto, los parámetros de la cadena se envían como UTF-16LE para las columnas nvarchar y según la clasificación de la base de datos para las columnas varchar:
| Tipo de columna | Codificación por cable | Resultado en Python |
|---|---|---|
nvarchar, nchar, ntext |
UTF-16LE |
str (descifrado por el conductor) |
varchar, char, text |
Codificación de bases de datos o de columnas |
str (decodificado por el controlador usando la codificación fuente) |
Las cadenas de Python siempre son Unicode internamente. Cuando pasas un str parámetro, el controlador lo codifica para el tipo de columna objetivo. Por defecto, el controlador envía los parámetros de cadena como nvarchar (Unicode), lo que garantiza que los caracteres se conserven independientemente de la clasificación de la base de datos. En las columnas varchar, UTF-8 solo se aplica cuando la base de datos o la columna usa una intercalación compatible con UTF-8.
Si tu columna es varchar y necesitas enviar datos no Unicode para que coincidan exactamente con el tipo de columna (por ejemplo, para evitar advertencias de conversión implícitas), úsalo setinputsizes() para anular el valor por defecto:
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
# Create temp table for demo
cursor.execute("CREATE TABLE #AsciiTable (Code VARCHAR(100))")
cursor.setinputsizes([(mssql_python.SQL_VARCHAR, 100, 0)])
cursor.execute(
"INSERT INTO #AsciiTable (Code) VALUES (?)",
("ABC123",)
)
conn.commit()
Para la mayoría de las aplicaciones, el comportamiento por defecto es el correcto. Anula solo cuando veas advertencias de conversión implícitas en los planes de consulta o necesites coincidir con una clasificación específica varchar .
Codificación de conexión
El controlador mssql-python gestiona automáticamente la codificación de la conexión según la versión y configuración de Microsoft SQL Server. Como las cadenas de Python son Unicode, el controlador las codifica adecuadamente (UTF-8 o UTF-16) para el tipo de dato objetivo. No necesitas configurar la codificación de conexiones manualmente.
Columnas VARCHAR con colaciones heredadas
Las bases de datos con colaciones de Windows-1252 (CP1252), como Latin1_General_CI_AS, almacenan caracteres latinos extendidos (por ejemplo, €, ™, y caracteres acentuados) en varchar columnas usando la codificación CP1252. El controlador decodifica correctamente estos caracteres en todas las plataformas.
Esta diferencia es importante para despliegues multiplataforma: los mismos varchar datos que se leen correctamente en Windows también se leen correctamente en Linux, sin necesidad de configuración especial.
# Create a temp table with a varchar column and insert extended Latin characters
cursor.execute("CREATE TABLE #Products (Name VARCHAR(100))")
cursor.execute("INSERT INTO #Products (Name) VALUES (%(name)s)", {"name": "Café €100 ™"})
conn.commit()
# CP1252 characters in varchar columns are decoded correctly on all platforms
cursor.execute("SELECT Name FROM #Products WHERE Name LIKE '%€%'")
for row in cursor:
print(row.Name) # Correct on both Windows and Linux
Si tu esquema lo permite, migrar varchar columnas a nvarchar evita por completo la ambigüedad de codificación y soporta todos los caracteres Unicode.
Codificación de archivos
Al leer archivos para insertar en la base de datos, especifica la codificación adecuada para preservar el contenido Unicode.
# Reading files with explicit encoding
def insert_file_content(cursor, conn, file_path: str, encoding: str = "utf-8"):
with open(file_path, "r", encoding=encoding) as f:
content = f.read()
cursor.execute(
"INSERT INTO #FileContent (Content) VALUES (%(content)s)",
{"content": content}
)
conn.commit()
Operaciones comunes con cadenas
Estos ejemplos cubren patrones comunes de manipulación de cadenas tanto en Python como en SQL.
Concatenación
Puedes concatenar cadenas ya sea en Python antes de insertarlas o usando los operadores de cadenas de SQL en el servidor.
# Concatenate in Python before insert
first_name = "Alice"
last_name = "Smith"
full_name = f"{first_name} {last_name}"
cursor.execute("""
CREATE TABLE #ConcatDemo (
ID INT IDENTITY(1,1) PRIMARY KEY,
FullName NVARCHAR(200)
)
""")
cursor.execute(
"INSERT INTO #ConcatDemo (FullName) VALUES (%(name)s)",
{"name": full_name}
)
# Or concatenate in SQL
cursor.execute("""
SELECT FirstName + ' ' + LastName AS FullName FROM Person.Person
""")
Formato de cadena
Aplica el formato en Python para mostrar cadenas con moneda, relleno o alineación antes de mostrarlas a los usuarios.
from decimal import Decimal
# Format for display
cursor.execute("SELECT Name, ListPrice FROM Production.Product WHERE ListPrice > 0")
for row in cursor.fetchall()[:5]:
print(f"{row.Name}: ${row.ListPrice:.2f}")
# Pad strings
cursor.execute("SELECT ProductNumber FROM Production.Product")
for row in cursor.fetchall()[:5]:
padded = row.ProductNumber.ljust(15) # Left-justify, pad to 15 chars
print(f"[{padded}]")
NULL frente a cadena vacía
Microsoft SQL trata NULL y cadena vacía ('') como valores diferentes. NULL significa "desconocido" mientras que cadena vacía significa "conocida por estar vacía". Elige una convención para tu solicitud y sé consistente. La mayoría de las aplicaciones usan NULL para los campos opcionales que faltan.
El siguiente ejemplo demuestra cómo distinguir entre cadena NULL y cadena vacía:
# NULL is different from empty string
cursor.execute("""
CREATE TABLE #NullDemo (
ID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(100),
MiddleName NVARCHAR(100)
)
""")
cursor.execute("""
INSERT INTO #NullDemo (Name, MiddleName)
VALUES (%(name)s, %(middle)s)
""", {"name": "Alice", "middle": None}) # NULL
cursor.execute("""
INSERT INTO #NullDemo (Name, MiddleName)
VALUES (%(name)s, %(middle)s)
""", {"name": "Bob", "middle": ""}) # Empty string
# Query differences
cursor.execute("SELECT * FROM #NullDemo WHERE MiddleName IS NULL")
cursor.execute("SELECT * FROM #NullDemo WHERE MiddleName = ''")
Operaciones de recorte
Utiliza los métodos de cadena de Python para eliminar los espacios en blanco iniciales, finales o ambos de los valores recuperados de la base de datos.
cursor.execute("SELECT Name FROM Production.Product")
for row in cursor:
# Remove whitespace
trimmed = row.Name.strip() # Both ends
left_trimmed = row.Name.lstrip()
right_trimmed = row.Name.rstrip()
Datos de cadenas JSON
Almacena documentos JSON en columnas nvarchar(max) y consulta con las funciones JSON de Microsoft SQL.
Almacenar JSON como nvarchar
Serializar diccionarios de Python en cadenas JSON e insertarlos en columnas nvarchar; recuperarlos y desserializarlos de nuevo en objetos Python.
import json
data = {"name": "Alice", "scores": [95, 87, 91], "active": True}
json_string = json.dumps(data)
cursor.execute("""
CREATE TABLE #Configs (
ID INT IDENTITY(1,1) PRIMARY KEY,
ConfigData NVARCHAR(MAX)
)
""")
cursor.execute("""
INSERT INTO #Configs (ConfigData) VALUES (%(data)s)
""", {"data": json_string})
# Retrieve and parse
cursor.execute("SELECT ConfigData FROM #Configs WHERE ID = 1")
row = cursor.fetchone()
config = json.loads(row.ConfigData)
print(config["name"]) # 'Alice'
Utiliza funciones JSON SQL de Microsoft
Utiliza las funciones JSON de Microsoft SQL para analizar y filtrar los datos JSON directamente en consultas en lugar de en el código cliente.
import json
data = {"name": "Alice", "scores": [95, 87, 91], "active": True}
cursor.execute("""
CREATE TABLE #Configs (
ID INT IDENTITY(1,1) PRIMARY KEY,
ConfigData NVARCHAR(MAX)
)
""")
cursor.execute(
"INSERT INTO #Configs (ConfigData) VALUES (%(data)s)",
{"data": json.dumps(data)}
)
conn.commit()
cursor.execute("""
SELECT JSON_VALUE(ConfigData, '$.name') AS Name
FROM #Configs
WHERE JSON_VALUE(ConfigData, '$.active') = 'true'
""")
for row in cursor:
print(row.Name) # 'Alice'
Búsqueda de texto completo
Úsalo LIKE para la comparación de patrones, o activa un índice de texto completo para búsquedas de texto más avanzadas.
Consultas en texto completo
El LIKE operador con patrones comodines ofrece una alternativa directa a la búsqueda en texto completo cuando no hay un índice completo disponible.
# Using CONTAINS (requires full-text index on the table)
cursor.execute("""
SELECT JobTitle FROM HumanResources.Employee
WHERE JobTitle LIKE %(search)s
""", {"search": "%Engineer%"})
# Pattern-based search as an alternative to full-text
cursor.execute("""
SELECT Name FROM Production.Product
WHERE Name LIKE %(search)s
""", {"search": "%Mountain%"})
procedimientos recomendados
Aplica estas directrices para manejar correctamente los datos de cadenas en lenguajes y codificaciones.
Utiliza nvarchar para datos internacionales
Si no estás seguro de si una columna puede contener Unicode, usa nvarchar. El coste de almacenamiento es modesto y evita la pérdida de datos por conversión de caracteres.
El siguiente ejemplo muestra la diferencia entre definir columnas para datos Unicode y solo ASCII:
-- Good: supports any language
CREATE TABLE #UserProfile (
Name NVARCHAR(100),
Bio NVARCHAR(MAX)
);
-- Limited: ASCII/Latin only
CREATE TABLE #UserProfileAscii (
Name VARCHAR(100),
Bio VARCHAR(MAX)
);
Validar la longitud de la cadena
Comprueba la longitud de la cadena en Python antes de insertarla para evitar errores de truncamiento y proporcionar mensajes de error significativos a los usuarios.
def safe_insert(cursor, name: str, max_length: int = 100):
"""Insert with length validation."""
if len(name) > max_length:
raise ValueError(f"Name exceeds {max_length} characters")
cursor.execute(
"INSERT INTO #UserProfile (Name) VALUES (%(name)s)",
{"name": name}
)
Maneja las cadenas binarias por separado
Distingue entre cadenas de texto (Pythonstr, SQLnvarchar) y datos binarios (Pythonbytes, SQLvarbinary) para evitar problemas de codificación.
binary_data = b'\x00\x01\x02' # bytes - use varbinary
text_data = "Hello" # str - use nvarchar