Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Microsoft SQL poskytuje několik typů řetězců, které mssql-python ovladač mapuje na objekty Pythonstr. Klíčové rozhodnutí je, zda použít varchar (ne-Unicode) nebo nvarchar (Unicode):
- Používejte
nvarcharje tehdy, když vaše data mohou obsahovat znaky mimo ASCII, například jména, adresy nebo uživatelsky generovaný obsah v jakémkoli jazyce. - Používejte
varcharje, když jsou data striktně ASCII (kódy, identifikátory, e-mailové adresy) a chcete šetřit místo.varcharpoužívá 1 bajt na znak;nvarcharpoužívá 2 bajty na znak.
| Typ SQL | Unicode | Maximální délka | Typ Pythonu |
|---|---|---|---|
char(n) |
Ne | 8 000 | str |
varchar(n) |
Ne | 8 000 | str |
varchar(max) |
Ne | 2 GB | str |
nchar(n) |
Yes | 4,000 | str |
nvarchar(n) |
Yes | 4,000 | str |
nvarchar(max) |
Yes | 2 GB | str |
text |
Ne | 2 GB (zastaralé) | str |
ntext |
Yes | 2 GB (zastaralé) | str |
Základní operace s řetězci
Ovladač mapuje všechny typy řetězců Microsoft SQL na objekty jazyka Python str.
Vložte a vytáhněte struny
Používejte parametrizované dotazy k bezpečnému vkládání a načítání řetězcových dat z databáze.
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'
Řetězce se speciálními znaky
Zvládejte uvozovky, úhlové závorky a další speciální znaky v řetězcích pomocí parametrizovaných dotazů.
# 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()
Podpora kódování Unicode
Používejte sloupce nvarchar a Python str k ukládání a načítání textu v jakémkoli jazyce.
Uložit text Unicode
Vložte Unicode obsah předáním Python řetězců parametrizovaným dotazům; ovladač je kóduje jako UTF-16LE pro sloupce 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 v různých písmech
Podporujte více jazyků a skriptů v jedné tabulce pomocí sloupců nvarchar a hromadných vkladů.
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()
Zajistěte sloupce nvarchar pro Unicode
Vždy definujte sloupce jako nvarchar místo varchar, pokud vaše data mohou obsahovat znaky mimo 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
);
Aspekty délky řetězce
Vyberte si mezi typy s pevnou délkou a proměnnou délkou podle toho, jak konzistentní jsou délky dat.
Pevná versus proměnná délka
Microsoft SQL doplňuje hodnoty char(n) koncovými mezerami na deklarovanou délku. Toto vyplňování plýtvá úložištěm pro data s proměnnou délkou, ale může zlepšit výkon u sloupců s pevnou šířkou, jako jsou kódy zemí. Použijte varchar(n) pro většinu řetězcových sloupců.
Následující příklad ukazuje rozdíl v tom, jak sloupce s doplňováním mezer a bez doplňování mezer zacházejí s načítáním dat:
# 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
Manipulace s vlečnými prostory
Při načítání dat ze sloupců typu char s pevnou délkou použijte rstrip() k odstranění doplňovacích mezer přidaných serverem 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}'")
Velké struny (typy MAX)
Typy nvarchar(max) and varchar(max) podporují řetězce až do 2 GB, ideální pro ukládání rozsáhlých textových dokumentů, JSON nebo XML obsahu.
# 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
Porovnání a třídění strun
Chování porovnávání řetězců v Microsoft SQL závisí na řazení nastaveném pro databázi nebo sloupec.
Citlivost na velikost písmen
Porovnávání řetězců v Microsoft SQL závisí na řazení. Ve výchozím nastavení většina databází používá sortaci bez rozlišení na velká písmena, ale tuto možnost lze přepsat pomocí klauzule 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"})
Porovnávání podle vzoru LIKE
Použijte operátor LIKE se zástupnými znaky k vyhledávání vzorů v řetězcích; speciální znaky zapište pomocí hranatých závorek, aby odpovídaly doslovně.
# 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)}%"})
Úvahy ohledně kódování
Chování kódování závisí na typu sloupce v Microsoft SQL a na kolaci zdroje.
Předpoklady kódování a Unicode výchozí nastavení
Ovladač mssql-python automaticky zpracovává kódování na základě typu sloupce Microsoft SQL. Ve výchozím nastavení se řetězcové parametry odesílají jako UTF-16LE pro sloupce nvarchar a podle řazení databáze pro sloupce varchar:
| Typ sloupce | Drátové kódování | Výsledek Python |
|---|---|---|
nvarchar, nchar, ntext |
UTF-16LE |
str (rozluštěno řidičem) |
varchar, char, text |
Kódování třídění databází nebo sloupců |
str (dekódováno ovladačem pomocí kódování zdroje) |
Python řetězce jsou vždy interně Unicode. Když předáte parametr str, ovladač ho zakóduje pro typ cílového sloupce. Ve výchozím nastavení ovladač odesílá parametry řetězce jako ( nvarchar Unicode), což zajišťuje, že znaky jsou zachovány bez ohledu na klasifikaci databáze. Pro varchar sloupce se UTF-8 uplatňuje pouze tehdy, když databáze nebo sloupec používá kolaci s podporou UTF-8.
Pokud má váš sloupec typ varchar a potřebujete odesílat data jiná než Unicode, aby přesně odpovídala typu sloupce (například abyste se vyhnuli upozorněním na implicitní převod), použijte setinputsizes() k přepsání výchozího nastavení:
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()
Ve většině aplikací je výchozí chování správné. Přepsat pouze tehdy, když v plánech dotazů vidíte varování na implicitní převod nebo když potřebujete použít konkrétní kolaci varchar.
Kódování spojení
Ovladač mssql-python automaticky zajišťuje kódování připojení na základě verze a konfigurace Microsoft SQL Server. Protože řetězce v Python jsou Unicode, ovladač je správně kóduje (UTF-8 nebo UTF-16) pro cílový datový typ. Není potřeba ručně konfigurovat kódování připojení.
Sloupce VARCHAR se starším řazením
Databáze s řazením Windows-1252 (CP1252), například Latin1_General_CI_AS, ukládají rozšířené latinské znaky (například €, ™ a znaky s diakritikou) do sloupců varchar pomocí kódování CP1252. Ovladač tyto znaky správně dekóduje na všech platformách.
Tento rozdíl je důležitý pro multiplatformní nasazení: stejná varchar data, která se čtou správně ve Windows, čtou správně i na Linuxu, bez nutnosti speciální konfigurace.
# 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
Pokud to vaše schéma umožňuje, migrace sloupců varchar na nvarchar se zcela vyhne nejednoznačnosti kódování a podporuje všechny znaky Unicode.
Kódování souborů
Při čtení souborů pro vložení do databáze určete vhodné kódování pro zachování Unicode obsahu.
# 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()
Běžné operace s řetězci
Tyto příklady pokrývají běžné vzory manipulace s řetězci jak v Python, tak v SQL.
Zřetězení
Řetězce můžete spojovat buď v Python před vložením, nebo pomocí SQL řetězcových operátorů na serveru.
# 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
""")
Formátování řetězců
Pomocí formátování v Pythonu můžete před zobrazením uživatelům upravit řetězce tak, aby zobrazovaly měnu, doplnění mezer nebo zarovnání.
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 versus prázdný řetězec
Microsoft SQL považuje NULL a prázdný řetězec ('') za různé hodnoty. NULL znamená „neznámý“, zatímco prázdný řetězec znamená, že je známo, že je prázdný. Zvolte pro svou aplikaci jednu konvenci a dodržujte ji důsledně. Většina aplikací používá NULL pro chybějící volitelné pole.
Následující příklad ukazuje, jak rozlišit mezi NULL a prázdným řetězcem:
# 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 = ''")
Operace oříznutí
Použijte řetězcové metody v Python k odstranění úvodních, závěrečných nebo obou mezerových míst z hodnot získaných z databáze.
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()
JSON řetězcová data
Ukládejte JSON dokumenty do sloupců nvarchar(max) a dotazujte je pomocí JSON funkcí Microsoft SQL.
Uložit JSON jako nvarchar
Serializujte Python slovníky do JSON řetězců a vložte je do sloupců nvarchar; načtěte je a deserializujte zpět do Python objektů.
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'
Používejte funkce Microsoft SQL JSON
Použijte JSON funkce Microsoft SQL pro analýzu a filtrování JSON dat přímo v dotazech místo v klientském kódu.
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'
Fulltextové vyhledávání
Použijte LIKE pro sladění vzorů, nebo povolte index plného textu pro pokročilejší vyhledávání textu.
Dotazy v plném textu
Operátor LIKE s divokými vzory poskytuje přímočarou alternativu k vyhledávání v plném textu, když není k dispozici index plného textu.
# 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%"})
Osvědčené postupy
Aplikujte tyto pokyny pro správné zpracování řetězcových dat napříč jazyky a kódováními.
Použijte nvarchar pro mezinárodní data
Pokud si nejste jisti, zda sloupec může obsahovat Unicode, použijte nvarchar. Náklady na úložiště jsou skromné a zabraňují ztrátě dat při konverzi znaků.
Následující příklad ukazuje rozdíl mezi definováním sloupců pro Unicode a data pouze s 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)
);
Validovat délku řetězce
Před vložením zkontrolujte délku řetězce v Python, abyste předešli chybám při zkrácení a poskytli uživatelům smysluplné chybové zprávy.
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}
)
Binární řetězce zpracovávejte odděleně
Rozlišujte mezi textovými řetězci (Pythonstr, SQLnvarchar) a binárními daty (Pythonbytes, SQLvarbinary), abyste se vyhnuli problémům s kódováním.
binary_data = b'\x00\x01\x02' # bytes - use varbinary
text_data = "Hello" # str - use nvarchar