我正在尝试使用OUTPUT
获取新插入行的ID。但是,我遇到了HY010错误。我使用的是以下查询/代码:
string = """
SET NOCOUNT ON;
DECLARE @NEWID TABLE(ID INT);
INSERT INTO dbo.t1 (Username, Age)
OUTPUT inserted.id INTO @NEWID(ID)
VALUES(?, ?)
SELECT ID FROM @NEWID
"""
cursor.execute(string, "John Doe", 35)
cursor.commit()
id = cursor.fetchone()[0]
最后一行id = cursor.fetchone()[0]
导致HY010错误(见下文)。任何建议将不胜感激!
pyodbc.Error: ('HY010', '[HY010] [Microsoft][ODBC SQL Server Driver]Function sequence error (0) (SQLFetch)')
答案 0 :(得分:4)
我能够重现您的问题,我能够通过在INSERT之后立即检索id
值并在提交之前检索来避免它。也就是说,而不是
cursor.execute(string, "John Doe", 35)
cursor.commit()
id = cursor.fetchone()[0]
我做了
cursor.execute(string, "John Doe", 35)
id = cursor.fetchone()[0] # although cursor.fetchval() would be preferred
cursor.commit()
答案 1 :(得分:2)
如果您将SQLAlchemy与engine
一起使用,则可以在运行查询和获取表ID之前检索这样的PyODBC游标。
connection = sql_alchemy_engine.raw_connection()
cursor = connection.cursor()
result = cursor.execute(
"""
INSERT INTO MySchema.MyTable (Col1, Col2) OUTPUT INSERTED.MyTableId
VALUES (?, ?);
""",
col1_value,
col2_value,
)
myTableId = cursor.fetchone()[0]
cursor.commit()
print("my ID is:", myTableId)
答案 2 :(得分:1)
对我来说,这仅适用于Azure SQL Serverless(使用 pyodbc == 4.0.28 ):
//REACT
import React, {useContext, useEffect, useState} from 'react';
//MUI COMPONENTS
import {
Grid,
IconButton,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
TextField,
Typography,
useMediaQuery,
useTheme,
} from '@material-ui/core';
//MUI ICONS
import {Close as CloseIcon, Done as DoneIcon, Edit as EditIcon, Refresh as RefreshIcon} from '@material-ui/icons';
//CONTEXTS
import {NewTagContext} from '../../providers/NewTagContext';
//CUSTOM COMPONENTS
import CreateFields from '../components/CreateFields';
import DeleteButton from '../components/DeleteButton';
//CONFIG FILES
import textFields from './config/textFields.json';
import constraints from './config/textFields.constraints.json';
const TagTable = () => {
//HOOKS START
const context = useContext(NewTagContext);
const {tags} = context;
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
//HOOKS END
//STATE START
useEffect(() => {
if (!context.tags) context.read();
}, [context]);
const initialState = {tagEditId: null, tag: null};
const [state, setState] = useState(initialState);
//STATE END
//FUNCTIONS START
const setEdit = (tag) => {
setState({
tagEditId: tag.id ? tag.id : null,
tag: {...tag},
});
};
const onEditSubmit = (e) => {
e.preventDefault();
context.update(state.tag);
setState(initialState);
};
const onEditClose = () => {
context.resetTag(state.tag);
setState(initialState);
};
//FUNCTIONS END
return (
<TableContainer component={Paper}>
<Table size="small">
<TableHead>
<TableRow>
<TableCell colSpan={2}>
<Grid container justify="flex-end" alignItems="center">
<Grid item xs={isMobile}>
<CreateFields entityName="tag" textFields={textFields} constraints={constraints}
createFunction={context.create}/>
</Grid>
<Grid item>
<IconButton onClick={context.read}><RefreshIcon/></IconButton>
</Grid>
</Grid>
</TableCell>
</TableRow>
<TableRow>
<TableCell>Tag Name</TableCell>
<TableCell align="right">Actions</TableCell>
</TableRow>
</TableHead>
<TableBody>
{tags && tags.map((tag, index) => (
<TableRow key={tag.id}>
<TableCell>
{state.tagEditId === tag.id ?
<form noValidate onSubmit={onEditSubmit}>
<TextField type="text" value={tag.name} label={state.tag.name} name="name"
fullWidth
autoFocus onFocus={(e) => e.target.select()}
onChange={(e) => context.handleChange(index, e)}/>
</form>
:
<Typography>{tag.name}</Typography>
}
</TableCell>
<TableCell align="right">
{state.tagEditId !== tag.id ?
<>
<IconButton color="inherit" onClick={() => setEdit(tag)}>
<EditIcon/>
</IconButton>
<DeleteButton deleteFunction={context.delete} entity={tag}/>
</>
:
<>
<IconButton color="primary" onClick={onEditSubmit}>
<DoneIcon/>
</IconButton>
<IconButton color="secondary" onClick={onEditClose}>
<CloseIcon/>
</IconButton>
</>
}
</TableCell>
</TableRow>
))
}
</TableBody>
</Table>
</TableContainer>
);
}
;
export default TagTable;