在 sql 查询中多次使用相同的参数
Use same parameter multiple times in sql query
我正在使用 pyodbc 和 Microsoft SQL 服务器
我正在尝试在 python 中复制一个存储过程,其中针对每个 @currentSurveyId
执行此查询
SELECT *
FROM
(
SELECT
SurveyId,
QuestionId,
1 as InSurvey
FROM
SurveyStructure
WHERE
SurveyId = @currentSurveyId
UNION
SELECT
@currentSurveyId as SurveyId,
Q.QuestionId,
0 as InSurvey
FROM
Question as Q
WHERE NOT EXISTS
(
SELECT *
FROM SurveyStructure as S
WHERE S.SurveyId = @currentSurveyId AND S.QuestionId = Q.QuestionId
)
) as t
ORDER BY QuestionId
在 Python 中,我目前有:
cursor.execute("""SELECT UserId FROM dbo.[User]""")
allSurveyID = cursor.fetchall()
for i in allSurveyID:
p = i
test = cursor.execute("""SELECT *
FROM
(
SELECT
SurveyId,
QuestionId,
1 as InSurvey
FROM
SurveyStructure
WHERE
SurveyId = (?)
UNION
SELECT
(?) as SurveyId,
Q.QuestionId,
0 as InSurvey
FROM
Question as Q
WHERE NOT EXISTS
(
SELECT *
FROM SurveyStructure as S
WHERE S.SurveyId = (?)AND S.QuestionId = Q.QuestionId
)
) as t
ORDER BY QuestionId""",p)
for i in test:
print(i)
该参数只用一次(如果我从 UNION 开始删除所有内容)。当尝试在查询的其余部分使用相同的参数时,出现以下错误:('The SQL contains 3 parameter markers, but 1 parameters were supplied', 'HY000')
是否可以在同一个查询中多次使用同一个参数?
谢谢
pyodbc 本身仅支持“qmark”(位置)参数(参考:here),但对于 T-SQL(Microsoft SQL 服务器)我们可以使用 匿名代码块以避免多次传递相同的参数值:
cnxn = pyodbc.connect(connection_string)
crsr = cnxn.cursor()
sql = """\
SET NOCOUNT ON;
DECLARE @my_param int = ?;
SELECT @my_param AS original, @my_param * 2 AS doubled;
"""
results = crsr.execute(sql, 2).fetchone()
print(results) # (2, 4)
如果重复使用相同的参数值,只需乘以 one-item 参数列表:
cursor.execute(sql, [p]*3)
还考虑为需要两个 qmark 的 LEFT JOIN
(或 FULL JOIN
)重构您的 SQL:
SELECT DISTINCT
ISNULL(S.SurveyId, ?) AS SurveyId,
Q.QuestionId,
IIF(S.SurveyId IS NOT NULL, 1, 0) AS InSurvey
FROM Question Q
LEFT JOIN SurveyStructure S
ON S.QuestionId = Q.QuestionId
AND S.SurveyId = ?
ORDER BY Q.QuestionId
甚至可能只有一个参数:
SELECT MAX(S.SurveyId) AS SurveyId,
Q.QuestionId,
IIF(S.SurveyId IS NOT NULL, 1, 0) AS InSurvey
FROM Question Q
LEFT JOIN SurveyStructure S
ON S.QuestionId = Q.QuestionId
AND S.SurveyId = ?
GROUP BY Q.QuestionId,
IIF(S.SurveyId IS NOT NULL, 1, 0)
ORDER BY Q.QuestionId
我正在使用 pyodbc 和 Microsoft SQL 服务器
我正在尝试在 python 中复制一个存储过程,其中针对每个 @currentSurveyId
执行此查询SELECT *
FROM
(
SELECT
SurveyId,
QuestionId,
1 as InSurvey
FROM
SurveyStructure
WHERE
SurveyId = @currentSurveyId
UNION
SELECT
@currentSurveyId as SurveyId,
Q.QuestionId,
0 as InSurvey
FROM
Question as Q
WHERE NOT EXISTS
(
SELECT *
FROM SurveyStructure as S
WHERE S.SurveyId = @currentSurveyId AND S.QuestionId = Q.QuestionId
)
) as t
ORDER BY QuestionId
在 Python 中,我目前有:
cursor.execute("""SELECT UserId FROM dbo.[User]""")
allSurveyID = cursor.fetchall()
for i in allSurveyID:
p = i
test = cursor.execute("""SELECT *
FROM
(
SELECT
SurveyId,
QuestionId,
1 as InSurvey
FROM
SurveyStructure
WHERE
SurveyId = (?)
UNION
SELECT
(?) as SurveyId,
Q.QuestionId,
0 as InSurvey
FROM
Question as Q
WHERE NOT EXISTS
(
SELECT *
FROM SurveyStructure as S
WHERE S.SurveyId = (?)AND S.QuestionId = Q.QuestionId
)
) as t
ORDER BY QuestionId""",p)
for i in test:
print(i)
该参数只用一次(如果我从 UNION 开始删除所有内容)。当尝试在查询的其余部分使用相同的参数时,出现以下错误:('The SQL contains 3 parameter markers, but 1 parameters were supplied', 'HY000')
是否可以在同一个查询中多次使用同一个参数?
谢谢
pyodbc 本身仅支持“qmark”(位置)参数(参考:here),但对于 T-SQL(Microsoft SQL 服务器)我们可以使用 匿名代码块以避免多次传递相同的参数值:
cnxn = pyodbc.connect(connection_string)
crsr = cnxn.cursor()
sql = """\
SET NOCOUNT ON;
DECLARE @my_param int = ?;
SELECT @my_param AS original, @my_param * 2 AS doubled;
"""
results = crsr.execute(sql, 2).fetchone()
print(results) # (2, 4)
如果重复使用相同的参数值,只需乘以 one-item 参数列表:
cursor.execute(sql, [p]*3)
还考虑为需要两个 qmark 的 LEFT JOIN
(或 FULL JOIN
)重构您的 SQL:
SELECT DISTINCT
ISNULL(S.SurveyId, ?) AS SurveyId,
Q.QuestionId,
IIF(S.SurveyId IS NOT NULL, 1, 0) AS InSurvey
FROM Question Q
LEFT JOIN SurveyStructure S
ON S.QuestionId = Q.QuestionId
AND S.SurveyId = ?
ORDER BY Q.QuestionId
甚至可能只有一个参数:
SELECT MAX(S.SurveyId) AS SurveyId,
Q.QuestionId,
IIF(S.SurveyId IS NOT NULL, 1, 0) AS InSurvey
FROM Question Q
LEFT JOIN SurveyStructure S
ON S.QuestionId = Q.QuestionId
AND S.SurveyId = ?
GROUP BY Q.QuestionId,
IIF(S.SurveyId IS NOT NULL, 1, 0)
ORDER BY Q.QuestionId