Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Microsoft SQL oferuje wiele typów ciągów znaków, które sterownik mssql-python mapuje na obiekty Pythonstr. Kluczową decyzją jest, czy użyć varchar (nie-Unicode) czy nvarchar (Unicode):
- Używaj
nvarchar, gdy Twoje dane mogą zawierać znaki spoza ASCII, takie jak imiona, adresy lub treści generowane przez użytkowników w dowolnym języku. - Używaj
varchar, gdy dane są ściśle ASCII (kody, identyfikatory, adresy e-mail) i chcesz oszczędzać miejsce.varcharużywa 1 bajtu na znak;nvarcharużywa 2 bajtów na znak.
| Typ SQL | Unicode | Maksymalna długość | Typ języka Python |
|---|---|---|---|
char(n) |
No | 8,000 | str |
varchar(n) |
No | 8,000 | str |
varchar(max) |
No | 2 GB | str |
nchar(n) |
Yes | 4,000 | str |
nvarchar(n) |
Yes | 4,000 | str |
nvarchar(max) |
Yes | 2 GB | str |
text |
No | 2 GB (wycofane) | str |
ntext |
Yes | 2 GB (wycofane) | str |
Podstawowe operacje na ciągach
Sterownik mapuje wszystkie typy ciągów znaków Microsoft SQL na obiekty Python str.
Wstawiaj i wyciągaj struny
Używaj parametryzowanych zapytań do bezpiecznego wstawiania i pobierania danych łańcuchowych z bazy danych.
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'
Ciągi ze znakami specjalnymi
Obsługa cudzysłowów, nawiasów kątowych i innych znaków specjalnych w łańcuchach za pomocą parametryzowanych zapytań.
# 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()
Obsługa formatu Unicode
Używaj kolumn nvarchar i Python str do przechowywania i pobierania tekstu w dowolnym języku.
Zapisz tekst Unicode
Wstaw zawartość Unicode, przekazując ciągi Python do parametryzowanych zapytań; sterownik koduje je jako UTF-16LE dla kolumn 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 w różnych pismach
Wspieraj wiele języków i skryptów w jednej tabeli, używając kolumn nvarchar i wstawiań zbiorczych.
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()
Upewnij się, że kolumny mają typ nvarchar na potrzeby Unicode
Zawsze definiuj kolumny jako nvarchar zamiast varchar, gdy twoje dane mogą zawierać znaki nie-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
);
Rozważania dotyczące długości strun
Wybierz między typami o stałej długości a o zmiennej długości w zależności od tego, jak spójne są długości Twoich danych.
Stała a zmienna długość
char(n) w Microsoft SQL dopełnia wartości spacjami na końcu do zadeklarowanej długości. To wypełnienie marnuje miejsce na dane o zmiennej długości, ale może poprawić wydajność kolumn o stałej szerokości, takich jak kody krajów. Używaj varchar(n) w większości kolumn stringów.
Poniższy przykład pokazuje różnicę w sposobie, w jaki kolumny z wypełnianiem a bez wypełniania obsługują pobieranie danych:
# 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
Obsługa końcowych spacji
Podczas pobierania danych z kolumn char o stałej długości użyj rstrip(), aby usunąć spacje dopełniające dodawane przez 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}'")
Duże ciągi znaków (typy MAX)
Typy nvarchar(max) i varchar(max) obsługują ciągi znaków o rozmiarze do 2 GB, dzięki czemu idealnie nadają się do przechowywania dużych dokumentów tekstowych oraz zawartości JSON lub 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
Porównanie i sortowanie strun
Sposób porównywania ciągów znaków w Microsoft SQL zależy od sortowania ustawionego dla bazy danych lub kolumny.
Uwzględnij wielkość liter
Porównanie ciągów znaków w Microsoft SQL zależy od sortowania. Domyślnie większość baz danych używa sortowania bez rozróżniania wielkości liter, ale można to nadpisać klauzulą 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"})
Dopasowywanie wzorców LIKE
Używaj operatora LIKE ze znakami wieloznacznymi do wyszukiwania wzorców ciągów znaków; stosuj notację nawiasową dla znaków specjalnych, aby dopasować je dosłownie.
# 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)}%"})
Rozważania dotyczące kodowania
Sposób kodowania zależy od typu kolumny Microsoft SQL oraz źródłowych ustawień sortowania.
Założenia kodowania i domyślne ustawienia Unicode
Sterownik mssql-python automatycznie obsługuje kodowanie na podstawie typu kolumny Microsoft SQL. Domyślnie parametry tekstowe są wysyłane jako UTF-16LE dla kolumn nvarchar, a dla kolumn varchar zgodnie z ustawieniami sortowania bazy danych:
| Typ kolumny | Kodowanie przewodowe | Wynik Python |
|---|---|---|
nvarchar, nchar, ntext |
UTF-16LE |
str (odszyfrowane przez kierowcę) |
varchar, char, text |
Kodowanie zbiorcze bazy danych lub kolumn |
str (dekodowane przez sterownik przy użyciu kodowania źródłowego) |
Łańcuchy znaków w Pythonie są zawsze wewnętrznie reprezentowane w standardzie Unicode. Gdy przekazujesz parametr str, sterownik koduje go dla docelowego typu kolumny. Domyślnie sterownik wysyła parametry ciągu jako nvarchar (Unicode), co zapewnia, że znaki są zachowane niezależnie od zestawienia w bazie danych. W przypadku kolumn varchar kodowanie UTF-8 ma zastosowanie tylko wtedy, gdy baza danych lub kolumna używa sortowania obsługującego UTF-8.
Jeśli kolumna ma typ varchar i musisz wysłać dane inne niż Unicode, aby dokładnie odpowiadały typowi kolumny (na przykład aby uniknąć ostrzeżeń o niejawnej konwersji), użyj setinputsizes(), aby zastąpić ustawienie domyślne:
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()
W większości zastosowań domyślne zachowanie jest poprawne. Nadpisujesz tylko wtedy, gdy widzisz ukryte ostrzeżenia o konwersji w planach zapytań lub musisz dopasować konkretną varchar sortację.
Kodowanie połączeń
Sterownik mssql-python automatycznie obsługuje kodowanie połączenia na podstawie wersji i konfiguracji Microsoft SQL Server. Ponieważ ciągi Python są Unicode, sterownik koduje je odpowiednio (UTF-8 lub UTF-16) dla docelowego typu danych. Nie musisz ręcznie konfigurować kodowania połączeń.
Kolumny VARCHAR ze starszymi regułami sortowania
Bazy danych z kolacjami Windows-1252 (CP1252), takie jak Latin1_General_CI_AS, przechowują rozszerzone znaki łacińskie (na przykład €, ™, oraz znaki akcentowane) w varchar kolumnach z wykorzystaniem kodowania CP1252. Sterownik poprawnie dekoduje te znaki na wszystkich platformach.
Ta różnica ma znaczenie przy wdrożeniach międzyplatformowych: te same varchar dane, które odczytują poprawnie na Windows, odczytują poprawnie także na Linuksie, bez potrzeby specjalnej konfiguracji.
# 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
Jeśli Twój schemat na to pozwala, migracja kolumn z varchar do nvarchar całkowicie eliminuje niejednoznaczność kodowania i obsługuje wszystkie znaki Unicode.
Kodowanie plików
Podczas odczytu plików do wstawienia do bazy danych określ odpowiednie kodowanie, aby zachować zawartość 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()
Typowe operacje na ciągach
Te przykłady obejmują typowe wzorce manipulacji ciągami znaków zarówno w Python, jak i SQL.
Łączenie
Możesz łączyć łańcuchy w Python przed wstawieniem lub używać operatorów łańcuchów SQL na serwerze.
# 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
""")
Formatowanie ciągu
Zastosuj formatowanie w Python, aby wyświetlać ciągi znaków z walutą, wypełnieniem lub wyrównaniem przed ich pokazaniem użytkownikom.
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 kontra pusty ciąg
Microsoft SQL traktuje NULL i pusty ciąg ('') jako różne wartości. NULL oznacza "nieznany", natomiast pusty ciąg oznacza "wiadomo, że jest pusty". Wybierz jedną konwencję do swojej aplikacji i bądź konsekwentny. Większość aplikacji używa NULL dla brakujących pól opcjonalnych.
Poniższy przykład pokazuje, jak rozróżnić ciąg NULL od ciągu pustego:
# 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 = ''")
Operacje trimowania
Użyj metod ciągów znaków w Pythonie, aby usunąć białe znaki z początku, z końca lub z obu stron wartości pobranych z bazy danych.
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()
Dane łańcuchowe JSON
Przechowuj dokumenty JSON w kolumnach nvarchar(max) i zapytuj je za pomocą funkcji JSON Microsoft SQL.
Zapisz JSON jako nvarchar
Serializuj słowniki Python do ciągów JSON i wstaw je do kolumn nvarchar; pobierz i deserializuj je z powrotem do obiektów 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'
Użyj funkcji Microsoft SQL JSON
Używaj funkcji JSON Microsoft SQL do analizowania i filtrowania danych JSON bezpośrednio w zapytaniach zamiast w kodzie klienta.
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'
Wyszukiwanie pełnotekstowe
Zastosowanie LIKE do dopasowania wzorców lub włączenie indeksu pełnego tekstu dla bardziej zaawansowanego wyszukiwania tekstowego.
Zapytania pełnotekstowe
Operator LIKE używany z wzorcami wieloznacznymi zapewnia prostą alternatywę dla wyszukiwania pełnotekstowego, gdy indeks pełnotekstowy nie jest dostępny.
# 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%"})
Najlepsze rozwiązania
Stosuj te wytyczne, aby poprawnie obsługiwać dane ciągów znaków w różnych językach i kodowaniach.
Użyj nvarchar do danych międzynarodowych
Jeśli nie jesteś pewien, czy kolumna może zawierać Unicode, użyj nvarchar. Koszt przechowywania jest umiarkowany i zapobiega utracie danych podczas konwersji znaków.
Poniższy przykład pokazuje różnicę między definiowaniem kolumn dla danych Unicode a danych tylko 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)
);
Walidacja długości ciągu
Sprawdź długość ciągu w Pythonie przed wstawieniem, aby zapobiec błędom związanym z obcięciem danych i zapewnić użytkownikom czytelne komunikaty o błędach.
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}
)
Traktuj ciągi binarne osobno
Rozróżnij ciągi tekstowe (Pythonstr, SQLnvarchar) od danych binarnych (Pythonbytes, SQLvarbinary), aby uniknąć problemów z kodowaniem.
binary_data = b'\x00\x01\x02' # bytes - use varbinary
text_data = "Hello" # str - use nvarchar