tiberius icon indicating copy to clipboard operation
tiberius copied to clipboard

Query API -> Dynamic parameters

Open Cloud33 opened this issue 2 years ago • 2 comments

I recommend adding a new API to 'Query' to add dynamic SQL scripts.

Motivation: Some data in my foreground needs to be updated, and it will tell me which fields need to be modified, but I currently have no way to implement them well.

That's all I can do now

var user= xxx
var commands = vec![Update::Name,Update::Pwd]  //Fields to be modified
let mut update_sql = "UPDATE [dbo].[user] SET ";
for command in commands.iter() {
   match xxxx
         Update::Name => update_sql + = " Name=@P1"
         Update::Pwd=> update_sql + = " Pwd=@P2";
   xxx
};
let mut query = tiberius::Query::new(update_sql);
for command in commands.iter() {
   match xxxx
         Update::Name => query.bind(user.Name);
         Update::Pwd=> query.bind(user.Pwd);
   xxx
};

let results = query.execute(&mut client).await?;

"I hope it only takes' for 'once, or there's a better way, like C# (Linq):

var user = xxx
var data = Db.Update<User>xxxx;
for command in commands {
   switch(command )
         case Update::Id:  data.SetColumns(t => t.Id== user.Id);
   xxx
};

Cloud33 avatar Mar 17 '23 06:03 Cloud33

I'm not sure I understand exactly what you are trying to achieve, but if what you are trying to achieve is dynamically construct SQL statements, I recommend using a proper SQL grammar lib. sqlparser seems to be the leader of this pack. In your case, I think you want to look at Statement::Update which will allow you to construct Update statements. Once you have constructed one, you can statement.to_string() to get the SQL. Apart from solving the immediate problem, you are also protected against injection attacks (assuming the lib is sufficiently diligent).

If you want a full ORM, tiberius is not the right lib. You may want e.g. SeaORM.

UPDATE: That was impolite. For grammar libs there is also Prisma's own quaint. As far as I can tell, Prisma has no ORM geared toward Rust.

bittrance avatar Mar 18 '23 10:03 bittrance

Thank you for your reply. My idea is that I only need for once

like this:

var user= xxx
var commands = vec![Update::Name,Update::Pwd]  //Fields to be modified
let mut query = tiberius::Query::new();
for command in commands.iter() {
   match xxxx
         Update::Name => {
           query.sql + = " Name=@P1";
           query.bind(user.Name);
         },
         Update::Pwd=> {
           query.sql + = " Pwd=@P2";
           query.bind(user.Pwd)
         }
   xxx
};
let results = query.execute(&mut client).await?;

query.sql Can be dynamically assembled

Cloud33 avatar Mar 18 '23 11:03 Cloud33