Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Passing an Array into Titanium.Database.DB.execute

This does not seem to work. Crashes my app:

var conn = Titanium.Database.install('foo.db', 'foo');
var resultSet = conn.execute(
    'SELECT * FROM BAR WHERE id=? and id2=?', 
    [1,2]
);

The following syntax does work, but shouldn't the above work as well?

var conn = Titanium.Database.install('foo.db', 'foo');
var resultSet = conn.execute(
    'SELECT * FROM BAR WHERE id=? and id2=?', 
    1, 
    2
);
— asked September 12th 2010 by Bart Lewis
  • database
3 Comments
  • As noted below, this is a bug in the iOS Ti.Database implementation. I've hacked around it by wrapping conn.execute() into another function, switching on the OS type, and then for iOS having a gigantic switch statement of doom to emulate array-based query parameters. (I am building queries dynamically, so using the varargs format is simply not an option. I also tried the approaches below and none of them worked, either.)

    So far I'm up to 40 elements in my switch statement because of IN queries. This really needs to get fixed soon as it's a critical bug… Just fixing the docs doesn't help matters.

    — commented February 9th 2011 by Larry Garfield
  • Noticed this to be limited to iOS (array works fine in Android). Until this is fixed you may have to build a database execute string with your params and eval it. However, I'd recommend detecting the platform and passing the array on Android when possible as you may know eval is slow.

    — commented April 1st 2011 by Dan Boorn
  • Forgot to mention. Don't forget the ending semicolon on the eval for iOS.

    — commented April 1st 2011 by Dan Boorn

6 Answers

  • I think it should be array of objects.
    [{id:1},{id2:2}].

    — answered September 12th 2010 by Sravan Vinjamuri
    permalink
    2 Comments
    • I tried something like this, but it didn't seem to work either.

      var resultSet = conn.execute(
          'SELECT * FROM BAR WHERE id=:id and id2=:id2', 
           [{id:1},{id2:2}]
      );
      

      That would be a nice future enhancement…

      — commented September 13th 2010 by Bart Lewis
    • Slightly better then above syntax (which does not even work BTW), just putting it out there as a possible future enhancement to the syntax.

      var resultSet = conn.execute(
          'SELECT * FROM bar WHERE id=:id AND id2=:id2', 
           {id:1, id2:2}
      );
      

      — commented September 13th 2010 by Bart Lewis
  • Try using open on your DB rather than install

    — answered September 13th 2010 by Gary Everest
    permalink
    1 Comment
    • No help. Same effect: crash.

      — commented September 13th 2010 by Bart Lewis
  • Is there anything else in your code that is causing the crash?

    — answered September 13th 2010 by Gary Everest
    permalink
    1 Comment
    • Of course this is possible, but I don't think so. Is there a way to get more information from Titanium about a crash? A dump or trace or something of that nature?

      — commented September 13th 2010 by Bart Lewis
  • To pass in multiple arguments, you can simply keep adding them to the function call, as in this example.

    — answered January 22nd 2011 by Kevin Whinnery
    permalink
    5 Comments
    • That doesn't help if you need to build a query dynamically. I am building up a query string dynamically and do not know ahead of time how many parameters I will have, so an array form is mandatory.

      I've been trying to hack around this iOS limitation with either apply() or call(), but neither seem to be working.

      This should work:

      function query(stmt, args) {
        // this.connection is an instance of Ti.Database.DB
        // I've verified that is the case.
        var result = this.connection.execute.call(this.connection, arguments);
        return result;
      }
      

      But instead I get an error:

      TypeError: Cannot find function apply in object [KrollMethod execute].

      I get the same thing for call(), too.

      Any suggestions on a workaround until Titanium is fixed? This sounds like a critical bug to me.

      — commented January 23rd 2011 by Larry Garfield
    • Larry, this is what I ended up coming up with.

      var resultSet = Function.apply.call(conn.execute, conn, arguments);
      

      — commented January 29th 2011 by Bart Lewis
    • Bart, if this is your solution then please mark it as best, so that others can find it, as per the Participating in the Q&A guide. Thanks

      — commented January 29th 2011 by Paul Dowsett
    • I can confirm that Function.apply.call indeed does work. Thanks guys.

      — commented January 29th 2011 by Mick Staugaard
    • Paul, I hesitate to mark any of the current answers as "best". My "solution" above is really a work-around.

      — commented January 29th 2011 by Bart Lewis
  • Ticket #2917 has been opened to correct the docs.

    However, check out the substitution examples in the SQLite Databases guide, which are correct.

    — answered January 22nd 2011 by Paul Dowsett
    permalink
    0 Comments
  • I also have this problem. I there any chance we will see a fix for this any time soon?

    — answered January 29th 2011 by Mick Staugaard
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.