SQLite中的“如果不存在则插入”语句

时间:2013-10-12 17:19:53

标签: sqlite constraints sql-insert

我有一个SQLite数据库。我试图在表users_id中插入值(lessoninfo_idbookmarks),但前提是它们之前不存在。

INSERT INTO bookmarks(users_id,lessoninfo_id) 
VALUES(
    (SELECT _id FROM Users WHERE User='"+$('#user_lesson').html()+"'),
        (SELECT _id FROM lessoninfo 
        WHERE Lesson="+lesson_no+" AND cast(starttime AS int)="+Math.floor(result_set.rows.item(markerCount-1).starttime)+") 
        WHERE NOT EXISTS (
            SELECT users_id,lessoninfo_id from bookmarks 
            WHERE users_id=(SELECT _id FROM Users 
            WHERE User='"+$('#user_lesson').html()+"') AND lessoninfo_id=(
                SELECT _id FROM lessoninfo
                WHERE Lesson="+lesson_no+")))

这会出错:

  

db error附近的语法。

4 个答案:

答案 0 :(得分:373)

如果您不想要重复,则应将其声明为表约束:

CREATE TABLE bookmarks(
    users_id INTEGER,
    lessoninfo_id INTEGER,
    UNIQUE(users_id, lessoninfo_id)
);

(两列上的主键都会产生相同的效果。)

然后可以告诉数据库您想要silently ignore records that would violate such a constraint

INSERT OR IGNORE INTO bookmarks(users_id, lessoninfo_id) VALUES(123, 456)

答案 1 :(得分:107)

如果您有一个名为memos的表,其中包含两列idtext,您应该可以这样做:

INSERT INTO memos(id,text) 
SELECT 5, 'text to insert' 
WHERE NOT EXISTS(SELECT 1 FROM memos WHERE id = 5 AND text = 'text to insert');

如果记录已包含text等于'要插入的文本'且id等于5的行,则将忽略插入操作。

我不知道这是否适用于您的特定查询,但它可能会为您提供有关如何继续的提示。

我建议您改为设计表格,以便不允许重复,如下面@CLs answer中所述。

答案 2 :(得分:10)

对于唯一列,请使用:

export default class PostList extends Component<{}> 
{

   constructor(props) {
      super(props);
      this._executeQuery('https://website.com/xml-feed/');
      this.state = {
        resultsLoaded: false,
        results: false,
      };
    };

  _keyExtractor = (item, index) => index;
  _renderItem = ({item, index}) => (
      <ListItem
        item={item}
        index={index}
        onPressItem={this._onPressItem}
      />
    );
    _renderList = (response) => {
        return <FlatList
        data={response.rss.channel[0].item}
        keyExtractor={this._keyExtractor}
        renderItem={this._renderItem}
      />;
    };
    _handleResponse = (response) => {
        var parseString = require('react-native-xml2js').parseString;
        var self = this;
        this.setState({ resultsLoaded: true });
        parseString(response, function (err, result, self) {
            console.log(self);
            self.setState({ resultsLoaded: true, results: self._renderList(result) });
        });
    };
    _executeQuery = (query) => {
      fetch(query)
          .then(response => response.text())
          .then(str => this._handleResponse(str))
          .catch(error =>
             console.log('ERROR: '+error)
         );
    };

  render() {
    const results = this.state.resultsLoaded ?
        this.state.results : null;
    const loading = !this.state.resultsLoaded ?
            (<View><Text style={styles.description}>
          Loading Blog Posts
        </Text>
        <ActivityIndicator size='large'/></View>) : null;
            console.log(this.state.resultsLoaded);
    return (
      <View style={styles.container}>
        {loading}
        {results}
      </View>
    );
  };

}

有关详细信息,请参阅:system-wide temporary directory

答案 3 :(得分:2)

i==vec.size()-2

这是最快的方法。

对于其他一些SQL引擎,您可以使用包含1条记录的Dummy表。 e.g:

insert into bookmarks (users_id, lessoninfo_id)

select 1, 167
EXCEPT
select user_id, lessoninfo_id
from bookmarks
where user_id=1
and lessoninfo_id=167;