So I'm trying to do a count query within a command from lua SQL, using a mySQL database. I want to get the current count of users within a table, however I'm quite lost with using lua as a language and incorporating a database to it.
So far, this is what I have:
exec,err = connect:execute("SELECT count(user_id) AS count FROM Users")
testString = string.format("%d", exec:numrows())
if exec:numrows() == 0 then
send_msg(receiver, teststring, ok_cb, false)
end
I've checked it with another script and it's value that it returns is 1, however I want to get the value within the row... How would I go about doing this with luaSQL?
Okay instead of making this harder on myself, I just decided to remove the count command from the SQL statement, and use the numrows statement within luaSQL, kind of like this:
exec,err = connect:execute("SELECT user_id FROM Users")
if exec:numrows() == 0 then
send_msg(receiver, "test", ok_cb, false)
end
Related
I have a table where I need to do two selections. First I need to find OBJ where uunn = abc. Then I need to select where OBJ equals the first result but it doesn't work.
Example:
SELECT OBJ INTO #obj FROM wddt WHERE `uunn`='abc' AND `mqr`='ps';
SELECT mqr FROM wddt WHERE `OBJ` = #obj AND `uunn`='as';
My goal is to check if mqr has a certain content, and I will compare that content in my PHP script.
Multi_query was disabled on the server I was trying to use, just tested everything using XAMPP and works like a charm. I didn't know multi-query could be disabled.
If you don't need the actual results of the first query you may use a subquery in the WHERE clause of the second one:
SELECT mqr FROM wddt WHERE `uunn`='as'
AND `OBJ` LIKE (SELECT OBJ FROM wddt WHERE `uunn`='abc' AND `mqr`='ps');
After trying to determine why my SQL statement was returning an error in the Node code I am refactoring to connect to MariaDB rather than via SQL Anywhere, I have narrowed it down to the REPLACE statement we use to compute how many records to process, and how many to skip.
My initial test SQL SELECT statement looks like this:
SELECT customer_name FROM ar.customers
We then use a REPLACE statement to, as I say, determine how many records to process, and how many to skip. When we were using SQL Anywhere that looked like this:
const sql = this.query.replace(/SELECT/i, `SELECT TOP ${recordsPerRun} START AT ${recordsProcessed + 1}`);
That syntax needs to change because MariaDB uses "LIMIT" instead of "TOP". And from my understanding, the first parameter will be the number of records to skip, and the second one how many to return.
So, in my case, it'd be something like:
LIMIT ${recordsProcessed}, ${recordsPerRun}
However, I can't quite get the full syntax right. How can I write this REPLACE statement in a way that will work with my initial test SQL SELECT statement from above? This seems tricky to do since in MariaDB LIMIT now goes at the end of the query, not at the beginning, like TOP did for MySQL.
LIMIT goes at the end, so there's nothing to replace, just concatenate it:
const sql = this.query + ` LIMIT ${recordsProcessed}, ${recordsPerRun}`;
or combine it into the template:
const sql = `${this.query} LIMIT ${recordsProcessed}, ${recordsPerRun}`;
so I'm currently working on a MySQL trigger. I'm trying to assign values to two variables when a new record is inserted. Below are the queries:
SET mssgDocNo = (SELECT Document_ID FROM CORE_MSSG WHERE Message_ID = new.MSSG_ID);
SET mssgRegime = (SELECT CONCAT (Regime_Type, Regime_Code) FROM T_DOC WHERE CD_Message_ID = new.MSSG_ID);;
For some reason, the second SQL query is not picking up the 'new.MSSG_ID' condition while the first query in same trigger recognizes it. I really can't figure out what seems to be the problem.
When I replace the 'new.MSSG_ID' with a hard-coded value from the database in the second query it seems to work. I doubt the 'new.MSSG_ID' is the problem because it works perfectly fine in the first query.
I've tried pretty much anything I could think of. Would appreciate the help.
I would write these more simply as:
SELECT mssgDocNo := Document_ID
FROM CORE_MSSG
WHERE Message_ID = new.MSSG_ID;
SELECT mssgRegime := CONCAT(Regime_Type, Regime_Code)
FROM T_DOC
WHERE CD_Message_ID = new.MSSG_ID;
The SET is not necessary.
I did make one other change that might make it work. I removed the space after CONCAT. Some versions of MySQL have trouble parsing spaces after function calls.
This should be the simplest thing but for some reason it's eluding me completely.
I have a Sequel connection to a database named DB. It's using the Mysql2 engine if that's important.
I'm trying to update a single record in a table in the database. The short loop I'm using looks like this:
dataset = DB["SELECT post_id, message FROM xf_post WHERE message LIKE '%#{match}%'"]
dataset.each do |row|
new_message = process_message(row[:message])
# HERE IS WHERE I WANT TO UPDATE THE ROW IN THE DATABASE!
end
I've tried:
dataset.where('post_id = ?', row[:post_id]).update(message: new_message)
Which is what the Sequel cheat sheet recommends.
And:
DB["UPDATE xf_post SET message = ? WHERE post_id = ?", new_message, row[:post_id]]
Which should be raw SQL executed by the Sequel connector. Neither throws an error or outputs any error message (I'm using a logger with the Sequel connection). But both calls fail to update the records in the database. The data is unchanged when I query the database after running the code.
How can I make the update call function properly here?
Your problem is you are using a raw SQL dataset, so the where call isn't going to change the SQL, and update is just going to execute the raw SQL. Here's what you want to do:
dataset = DB[:xf_post].select(:post_id, :message).
where(Sequel.like(:message, "%#{match}%"))
That will make the where/update combination work.
Note that your original code has a trivial SQL injection vulnerability if match depends on user input, which this new code avoids. You may want to consider using Dataset#escape_like if you want to escape metacharacters inside match, otherwise if match depends on user input, it's possible for users to use very complex matching syntax that the database may execute slowly or not handle properly.
Note that the reason that
DB["UPDATE xf_post SET message = ? WHERE post_id = ?", new_message, row[:post_id]]
doesn't work is because it only creates a dataset, it doesn't execute it. You can actually call update on that dataset to run the query and return number of affected rows.
I have a table with server names and logins. I need to retrieve the logins that are common across a group of servers.
Given the following data:
ServerName Login
-------------------------------
Server1 User1
Server2 User1
Server2 User2
I would pass in Server1,Server2 and get back only User1 as User2 is not associated Server1.
Can anyone tell me how this would be achieved in LINQ to SQL?
I have tried Contains but that returns me all users on any of the servers which is kind of the opposite to what I'm looking for.
EDIT: One of my colleagues managed to write the SQL version of what I'm after....
SELECT Login
FROM ServerLogins
WHERE ServerName IN ('Server1', 'Server2')
GROUP BY Login
HAVING count(Login) = 2
but neither of us know how to translate this into a LINQ query.
ADDITIONAL EDIT:
With Ryan's help and some Googling of the differences in LINQ between VB and C# I got the following to work.
Dim logins = From l In dc.ServerLogins _
Where servers.Contains(l.ServerName) _
Group l By l.Login Into Group _
Where Group.Count() = servers.Count _
Select Login
Thanks again to everyone for their help.
Nick
Here is what I came up with. You'll probably want to check and find out what SQL it actually generates if you're worried about it.
List<string> servers = new List<string>{"Server1", "Server2"};
var logins = from l in context.ServerLogins
where servers.Contains(l.ServerName)
group l by l.Login into g
where g.Count() == servers.Count
select g.Key;
Personally I think this is a good place NOT to use Linq to SQL and instead to use either a sproc or a standard SQL query. I think that even if you were to come up with the correct query in Linq, it would not be very readable and/or efficient.
The SQL you would have would look something like this:
SELECT Login
FROM ServerLogins
WHERE ServerName IN ('Server1', 'Server2')
GROUP BY Login
HAVING COUNT(*) = 2
Note that the "2" in the last line should be replaced with the number of server names in the list above ("IN ('Server1', 'Server2')").
As long as there's a reasonable practical limit on the # of servers being passed in I'd go with something like this:
public ICollection<Login> GetLoginsForServers(params string[] servers)
{
if (servers == null || servers.Length == 0)
return new List<Login>();
var logins = db.Logins.Where(p => p.ServerName == servers[0]);
for (int i=1; i<servers.Length; i++)
{
logins = logins.Intersect(db.Logins.Where(p => p.ServerName == servers[i]));
}
return logins.ToList();
}
Basically you're starting with all the logins associated with the first server then limiting it by those associated with each subsequent. Since the query doesn't get executed until ToList() you still only query the database once, and although the query itself is bound to be ugly, the hope is that the LINQ2SQL provider generates something that will result in an efficient query plan.