使用https://blogs.oracle.com/oraclemagazine/on-cursors-sql-and-analytics
,
我创建了一种将数组绑定到SQL语句的方法,尽管可能不是最好的方法。
初始:
cursor.execute("Select * from table where column in (:id)",{"id":('A','B')})
我按照上面的说明将其更改为:
cursor.execute(with data as (select trim(substr(txt, instr(txt, ',', 1, level ) + 1,
instr (txt, ',', 1, level+1) - instr (txt, ',', 1, level) -1 ) ) as token
from (select ','||:txt||',' txt from dual)
connect by level <= length(:txt)-length(replace(:txt,',',''))+1)
Select *
from table
where column in (select * from data)",{"txt":"A,B"})
现在我遇到一个问题,如果列表大于1000,则字符串参数越过4000字节标记,无法再处理它。
我如何使其工作?
[我只有“选择”权限,不能创建临时表]
答案 0 :(得分:1)
将大量id作为参数传递的整个想法是错误的方法。如果您出于“教育”目的而这样做,那么可以-做到这一点。对于生产环境,这是一个盲区。从我的经验可以看出,这可能会导致严重的问题。您仅需要解析查询就需要巨大的内存。我见过Django应用程序,开发人员在该数据库中向Oracle DB查询一些ID,然后根据这些ID发送另一个查询以查询其他数据,这些ID作为列表传递-就像您的查询一样:
import React, { Component } from 'react';
import './App.css';
import { random } from 'lodash';
import Button from './components/Button';
class App extends Component {
constructor(props) {
super(props);
this.state = {
quotes: [],
randomQuoteIndex: null,
isDoneFetching: false
}
}
componentDidMount() {
fetch('https://gist.githubusercontent.com/nataliecardot/0ca0878d2f0c4210e2ed87a5f6947ec7/raw/1802a693d02ea086817e46a42413c0df4c077e3b/quotes.json')
// Takes a JSON response string and parses it into JS object
.then(response => response.json())
// state is set to quotes: quotes due to destructuring
// Using setState callback since setState is asynchronous and need to make sure quotes is loaded before setting the randomQuoteIndex state since it depends on it
.then(quotes => this.setState({ quotes }, () => {
this.setState({
randomQuoteIndex: this.randomQuoteIndex(),
isDoneFetching: true
})
}))
}
get randomQuote() {
return this.state.quotes[this.state.randomQuoteIndex];
}
randomQuoteIndex() {
return random(0, this.state.quotes.length - 1);
}
render() {
return (
<div className="App" id="quote-box">
{this.state.isDoneFetching ? this.randomQuote.quote : 'Loading...'}
<Button
buttonDisplayName="Next"
clickHandler={this.blah}
/>
</div>
);
}
}
export default App;
问题在于,在某些情况下,该列表确实很大(大约400KB的数据,我已经看到在查询中放置了约57000个id的跟踪)。整个查询的大小为433KB!太疯狂了!最荒谬的事实是,与执行查询(几秒钟)相比,解析花费了更长的时间(约15分钟!)。
我认为通过巨大的查询(大小)是一个可怕的主意,您应该重新设计代码。
您可以做什么:
很难说对最终目标一无所知。
如果您仅出于教育目的而这样做,则(对于当前查询)请尝试使用CLOB类型(或在cx_oracle中为表示CLOB的对象)作为包含ID的字符串的存储。
编辑(2019-07-09)
示例(只是基于cx_oracle中示例的简单草稿):
select a,b,c
from table
where table.d in (<here was the list of all ids>)
;