Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Microsoft SQL tillhandahåller flera strängtyper som mssql-python-drivrutinen mappar till Python-objektstr. Det avgörande beslutet är om man ska använda varchar (icke-Unicode) eller nvarchar (Unicode):
- Använd
nvarcharnär din data kan innehålla tecken utanför ASCII, såsom namn, adresser eller användargenererat innehåll på vilket språk som helst. - Använd
varcharnär data strikt är ASCII (koder, identifierare, e-postadresser) och du vill spara lagring.varcharanvänder 1 byte per tecken;nvarcharanvänder 2 byte per tecken.
| SQL-typ | Unicode | Maxlängd | Python-typ |
|---|---|---|---|
char(n) |
No | 8,000 | str |
varchar(n) |
No | 8,000 | str |
varchar(max) |
No | 2 GB | str |
nchar(n) |
Ja | 4,000 | str |
nvarchar(n) |
Ja | 4,000 | str |
nvarchar(max) |
Ja | 2 GB | str |
text |
No | 2 GB (föråldrad) | str |
ntext |
Ja | 2 GB (föråldrad) | str |
Grundläggande strängåtgärder
Drivrutinen mappar alla Microsoft SQL-strängtyper till Python-objektstr.
Sätt in och hämta strängar
Använd parameteriserade frågor för att säkert infoga och hämta strängdata från databasen.
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'
Strängar med specialtecken
Hantera citattecken, vinkelparenteser och andra specialtecken i strängar med hjälp av parameteriserade frågor.
# 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()
Unicode-stöd
Använd nvarchar-kolumner och Python str för att lagra och hämta text i vilket språk som helst.
Lagra Unicode-text
Infoga Unicode-innehåll genom att skicka Python-strängar till parameteriserade frågor; drivrutinen kodar dem som UTF-16LE för nvarchar-kolumner.
# 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 i olika skript
Stöd flera språk och skript i en enda tabell genom att använda nvarchar-kolumner och bulkinsättningar.
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()
Säkerställ nvarchar-kolumner för Unicode
Definiera alltid kolumner som nvarchar istället för varchar när din data kan innehålla icke-ASCII-tecken.
-- 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
);
Stränglängdsöverväganden
Välj mellan typer med fast längd och variabel längd baserat på hur konsekventa dina datalängder är.
Fast kontra variabel längd
Microsoft SQL char(n) fyller ut värden med efterföljande mellanrum till den deklarerade längden. Denna utfyllning slösar bort lagring för data med variabel längd men kan förbättra prestandan för kolumner med fast bredd, såsom landskoder. Använd varchar(n) för de flesta strängkolumner.
Följande exempel visar skillnaden i hur utaddade och icke-vadderade kolumner hanterar datahämtning:
# 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
Hantera efterföljande utrymmen
När du hämtar data från kolumner med fast längd, använd rstrip() för att ta bort de utfyllnadsutrymmen som lagts till av 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}'")
Stora strängar (MAX-typer)
Och-typerna nvarchar(max)varchar(max) stödjer strängar upp till 2 GB, idealiskt för lagring av stora textdokument, JSON eller XML-innehåll.
# 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
Strängjämförelse och sortering
Microsoft SQL-strängjämförelsebeteende beror på sorteringsuppsättningen i databasen eller kolumnen.
Skiftlägesberoende
Microsoft SQL-strängsjämförelse beror på sorteringen. Som standard använder de flesta databaser kasus-insensitiv sortering, men du kan åsidosätta detta med klausulen 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"})
mönstermatchning med LIKE
Använd operatorn LIKE med joker-tecken för att söka efter strängmönster; escape-specialtecken med parentesnotation för att matcha literaler.
# 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)}%"})
Kodningsöverväganden
Kodningsbeteendet beror på Microsoft SQL-kolumntypen och källsorteringen.
Kodningsantaganden och Unicode-standardinställningar
Drivrutinen mssql-python hanterar kodning automatiskt baserat på Microsoft SQL-kolumntypen. Som standard skickas strängparametrar som UTF-16LE för nvarchar-kolumner och enligt databasens sortering för varchar-kolumner:
| Kolumntyp | Trådkodning | Python-resultat |
|---|---|---|
nvarchar, nchar, ntext |
UTF-16LE |
str (avkodad av föraren) |
varchar, char, text |
Databas- eller kolumnkollationskodning |
str (avkodas av drivrutinen med hjälp av källkodningen) |
Python-strängar är alltid Unicode internt. När du skickar en str parameter kodar drivrutinen den för målkolumntypen. Som standard skickar drivrutinen strängparametrar som nvarchar (Unicode), vilket säkerställer att tecken bevaras oavsett databassortering. För varchar kolumner gäller UTF-8 endast när databasen eller kolumnen använder en UTF-8-aktiverad sortering.
Om din kolumn är det varchar och du behöver skicka icke-Unicode-data för att matcha kolumntypen exakt (till exempel för att undvika implicita konverteringsvarningar), använd setinputsizes() för att åsidosätta standarden:
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()
För de flesta applikationer är standardbeteendet korrekt. Åsidosätt endast när du ser implicita konverteringsvarningar i frågeplaner eller behöver matcha en specifik varchar sortering.
Anslutningskodning
mssql-python-drivrutinen hanterar automatiskt kodning för anslutningen baserat på Microsoft SQL Server-versionen och konfigurationen. Eftersom Python-strängar är Unicode, kodar drivrutinen dem lämpligt (UTF-8 eller UTF-16) för måldatatypen. Du behöver inte konfigurera anslutningskodning manuellt.
VARCHAR-kolonner med äldre kollationer
Databaser med Windows-1252 (CP1252)-sorteringar, såsom Latin1_General_CI_AS, lagrar utökade latinska tecken (till exempel €, ™, och accentuerade tecken) i varchar kolumner med CP1252-kodning. Föraren avkodar dessa tecken korrekt på alla plattformar.
Denna skillnad är viktig för plattformsoberoende distributioner: samma varchar data som läses korrekt på Windows läses också korrekt på Linux, utan någon särskild konfiguration.
# 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
Om ditt schema tillåter det undviker du helt tvetydighet i kodningen genom att migrera kolumner till varcharnvarchar, och det stöder alla Unicode-tecken.
Filkodning
När du läser filer som ska infogas i databasen, ange lämplig kodning för att bevara Unicode-innehåll.
# 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()
Vanliga strängoperationer
Dessa exempel täcker vanliga mönster för strängmanipulation i både Python och SQL.
Sammanfogning
Du kan sammanfoga strängar antingen i Python innan du infogar eller använder SQL:s strängoperatorer på servern.
# 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
""")
Strängformatering
Använd formatering i Python för att visa strängar med valuta, utfyllnad eller justering innan du visar dem för användarna.
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 tom sträng
Microsoft SQL behandlar NULL och tom sträng ('') som olika värden. NULL betyder "okänd" medan tom sträng betyder "känd för att vara tom." Välj en konvention för din ansökan och var konsekvent. De flesta applikationer använder NULL för saknade valfria fält.
Följande exempel visar hur man skiljer mellan NULL och tom sträng:
# 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 = ''")
Trimning
Använd Pythons strängmetoder för att ta bort inledande, avslutande eller både inledande och avslutande blanktecken från värden som hämtats från databasen.
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-strängdata
Lagra JSON-dokument i nvarchar(max)-kolumner och fråga dem med Microsoft SQL:s JSON-funktioner.
Lagra JSON som nvarchar
Serialisera Python-ordböcker till JSON-strängar och infoga dem i nvarchar-kolumner; hämta och deserialisera dem tillbaka till 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'
Använd Microsoft SQL JSON-funktioner
Använd Microsoft SQL:s JSON-funktioner för att tolka och filtrera JSON-data direkt i frågor istället för i klientkod.
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'
Fulltextsökning
Använd LIKE för mönstermatchning, eller aktivera ett fulltextindex för mer avancerad textsökning.
Fulltextfrågor
Operatorn LIKE med wildcard-mönster ger ett enkelt alternativ till fulltextsökning när ett fulltextindex inte finns tillgängligt.
# 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%"})
Metodtips
Tillämpa dessa riktlinjer för att hantera strängdata korrekt över språk och kodningar.
Använd nvarchar för internationella data
Om du är osäker på om en kolumn kan innehålla Unicode, använd nvarchar. Lagringskostnaden är blygsam och det förhindrar dataförlust vid teckenkonvertering.
Följande exempel visar skillnaden mellan att definiera kolumner för Unicode och endast ASCII-data:
-- 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)
);
Validera stränglängd
Kontrollera stränglängden i Python innan du infogar för att undvika trunkeringsfel och ge meningsfulla felmeddelanden till användarna.
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}
)
Hantera binära strängar separat
Skilj mellan textsträngar (Pythonstr, SQLnvarchar) och binär data (Pythonbytes, SQLvarbinary) för att undvika kodningsproblem.
binary_data = b'\x00\x01\x02' # bytes - use varbinary
text_data = "Hello" # str - use nvarchar