When running this SQL code with join, I got an error:
ss= 'select project.id from project_list pl '
ss+= ' LEFT JOIN project p ON pl.project_id = p.id '
ss+= ' LEFT JOIN table t ON pl.table_id = t.id '
Error is :
OperationalError: (sqlite3.OperationalError) near "table":
syntax error [SQL: 'select project.id from project_list pl
LEFT JOIN project p ON pl.project_id = p.id LEFT JOIN table t
ON pl.table_id = t.id ']
This is not where the error comes from since the SQL statement looks correct.
This is using SQL Alchemy.
If you have a table named table, you need to quote it, or it causes a parsing error. This will work:
ss= 'select project.id from project_list pl '
ss+= ' LEFT JOIN project p ON pl.project_id = p.id '
ss+= ' LEFT JOIN "table" t ON pl.table_id = t.id '
This is because table is a reserved word in SQL (e.g. create table my_table, alter table mytable, etc.), and either the SQL parser is primitive, or the spec demands that it behave this way (PostgreSQL has the same problem).
I strongly encourage you to rename table to something else, if you can, or you're going to be in for a world of hurt. In other scenarios with SQLAlchemy or other DB libraries, when you're not hand-crafting the SQL, they may not be smart enough to automatically quote the table name. This will also cause you headaches if you migrate from SQLite to another database. It's likely to confuse people reading the code.
Related
My Exchange Server is very slow when delivering emails. It integrates with an SQL Server and I have the following SQL Queries in one script which I suspect is making it to slow down. Please can anyone help refactor this to make it faster?
<SELECT_tables_in_db>
select afa, afa from sys.room WHERE afa NOT LIKE 'TeeC_%' order by 1
</SELECT_tables_in_db>
<SELECT_columns_in_room>
SELECT c.afa AS column_name, y.afa as data_type, c.max_length,
CASE y.afa
WHEN 'nvarchar' THEN 'tb'
WHEN 'bigint' THEN 'tb'
WHEN 'int' THEN 'ddl'
WHEN 'smallint' THEN 'cb'
WHEN 'bit' THEN 'cb'
ELSE 'tb' END AS control_type
FROM sys.room AS t
JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
JOIN sys.types y on y.system_type_id = c.system_type_id
WHERE t.room = #tableName and y.afa <> 'sysname'
ORDER BY c.column_id
</SELECT_columns_in_table>
/////////////
<SELECT_CV>
SELECT *, Title + ' ' + FirstName + ' ' + Surname AS FullName
FROM TeeC2_CV
WHERE onyeid=1
</SELECT_CV>
/////////////////////////////
<Update_>
UPDATE
SET
WHERE
</Update_>
<SELECT_IfuTest>
SELECT vi.ebe_ID, vi.ife, vi.okwa
FROM TeeC2_Event vi
INNER JOIN dbo.vw_TEEC2_SalesMan SP ON vi.SalesManID = SP.SalesManID
INNER JOIN TeeC2_EventType ET ON vi.EventTypeID = vi.EventTypeID
INNER JOIN tblOnye U ON vi.UserID = U.UserID
</SELECT_IfuTest>
I’ve resolved it. The problem was coming from a wrong SMTP settings.
I almost have my EF Core query working... This is the SQL getting produced (notice the Count(*):
SELECT [u].[Key], [u].[Url], [u].[CreatedBy], [u].[CreatedOn], COUNT(*) AS [Clicks]
FROM [URLs] AS [u]
LEFT JOIN [OwnerUrls] AS [o] ON [u].[Key] = [o].[ShortUrlKey]
LEFT JOIN [Clicks] AS [c] ON [u].[Key] = [c].[ShortUrlKey]
GROUP BY [u].[Key], [u].[Url], [u].[CreatedBy], [u].[CreatedOn]
What I need is (have Count look at a specific column/table)
SELECT [u].[Key], [u].[Url], [u].[CreatedBy], [u].[CreatedOn], COUNT(c.ID) AS [Clicks]
FROM [URLs] AS [u]
LEFT JOIN [OwnerUrls] AS [o] ON [u].[Key] = [o].[ShortUrlKey]
LEFT JOIN [Clicks] AS [c] ON [u].[Key] = [c].[ShortUrlKey]
GROUP BY [u].[Key], [u].[Url], [u].[CreatedBy], [u].[CreatedOn]
Here is the EF Query that I'm using...
query = (from u in db.URLs
join ou in db.OwnerUrls on u.Key equals ou.ShortUrlKey into urlOwners
from subSet in urlOwners.DefaultIfEmpty()
join c in db.Clicks on u.Key equals c.ShortUrlKey into urlClicks
from subClicks in urlClicks.DefaultIfEmpty()
group subClicks by new { u.Key, u.Url, u.CreatedBy, u.CreatedOn } into g
select new ShortURL()
{
Key = g.Key.Key,
Url = g.Key.Url,
CreatedBy = g.Key.CreatedBy,
CreatedOn = g.Key.CreatedOn,
Clicks = g.Count()
});
I've tried changing the g.Count() to g.Select(x=>x.Id).Count() and that just causes EF Core to barf and complain about client side evaluation vs server side evaluation etc..
I should mention that the reason I'm joining the first model (OwnerUrls) is to support a where clause that I didn't include here...
Thanks!
I'm not a EF developer, but have worked with SQL Server for a while now. In SQL Server i would use COUNT(DISTINCT c.ID) to eliminate any duplicates you might get from JOINS.
If duplicates are impossible due to the model the COUNT(*) shoud be sufficient.
Maybe this might help:
https://entityframeworkcore.com/knowledge-base/51892585/linq-select-distinct-count-performed-in-memory
I created a whole bunch of SQLite database tables. Many columns in the tables have names with spaces, which I'm now realizing was not such a brilliant idea. Is there a way to write one command which will get rid of all spaces in all columns in all tables? I know I can do it one at a time (all potential duplicates seem to address this issue rather than my issue) but it's going to take me forever. Any ideas on how I can do this?
Use the following SQL to find all of the column names that contain spaces. I also included SQL to generate a new name.
SELECT t.name as tablename, c.name as badcol, replace(c.name, ' ','_') as newcolname
FROM sqlite_master t
JOIN pragma_table_info(t.name) c
WHERE t.type = 'table' AND c.name like '% %';
From here you would have to generate alter statements looking like this:
ALTER table <tablename> RENAME COLUMN <badcol> to <newcolname>;
While I cant figure how to directly pass the list of parms to the Alter table command you can use the following SQL to generate the alter commands for you then just copy/paste the result and execute the list of them.
SELECT ('ALTER TABLE ' || t.name || ' RENAME COLUMN ' || '[' || c.name || ']'
|| ' TO ' || '[' || REPLACE(c.name, ' ','_') || '];')
FROM sqlite_master t
JOIN pragma_table_info(t.name) c
WHERE t.type = 'table' AND c.name like '% %';
In this SQL I replaced the spaces in col names with underscores but you can see where you could replace the REPLACE function with the column renaming solution you desire.
I have a stored procedure that uses a variable called #Command (nvarchar(MAX)). I then add parameters accordingly based on given input.
declare #Command nvarchar(max)
if(#CaseFileID IS NOT NULL)
BEGIN
select #Command='
select [ServerCredentialsID],[CaseFileID],EIKSLT.[LocationType],EPT.PaymentType,[TaskID],[DateActive]
,[LengthOfPurchase],[Username],[Password],[IPDomain],[Port],[DES],[Website],[AmountPaid],[Latitude]
,[Longitude],[HasAttachments],[TimeStamp],[CaseElement],[Temporary],[StatusID]
FROM Element17a_IKSServerCredentials EIKSSC
JOIN ElementsIKSLocationTypes EIKSLT ON EIKSSC.LocationBeingUsedID= EIKSLT.IKSLocationBeingUsedID
JOIN ElementsPaymentTypes EPT ON EIKSSC.PaymentMethodID=EPT.PaymentTypeID
where EIKSSC.CaseFileID='''+cast(#CaseFileID as nvarchar(MAX))+''' '
#CaseFileID is declared as an int, and in the table it is an int. When I try
where EIKSSC.CaseFileID = ' + #CaseFileID + ' '
then the value doesn't even show (in the error it looks like "EIKSSC.CaseFileID= '" )
I just don't get it.
NOTE: SQL Server 2008 Management Studio
It's because #CaseFileID is VARCHAR even though you don't show it.
Your IF should be
if(#CaseFileID > '')
And if even that doesn't work, then you need to swap to LEFT joins because INNER JOINs will remove records that cannot be matched in the other 2 tables.
Finally, because CaseFileID is an int, you don't need the quotes. Even though SQL Server will implicitly cast '9' to the integer 9 in the WHERE clause, it's just not necessary.
declare #Command nvarchar(max)
if(#CaseFileID > '')
BEGIN
select #Command='
select [ServerCredentialsID],[CaseFileID],EIKSLT.[LocationType],EPT.PaymentType,[TaskID],[DateActive]
,[LengthOfPurchase],[Username],[Password],[IPDomain],[Port],[DES],[Website],[AmountPaid],[Latitude]
,[Longitude],[HasAttachments],[TimeStamp],[CaseElement],[Temporary],[StatusID]
FROM Element17a_IKSServerCredentials EIKSSC
LEFT JOIN ElementsIKSLocationTypes EIKSLT ON EIKSSC.LocationBeingUsedID= EIKSLT.IKSLocationBeingUsedID
LEFT JOIN ElementsPaymentTypes EPT ON EIKSSC.PaymentMethodID=EPT.PaymentTypeID
where EIKSSC.CaseFileID='+cast(#CaseFileID as nvarchar(MAX))
I have found what appears to be a bug in the SQLite JDBC driver, but I thought I'd see if someone could spot any boneheaded errors on my part. I have the following query:
SELECT
SKU_ATTR_VALUE.*,
Product.ProductID
FROM
SKU_ATTR_VALUE
INNER JOIN SKU
ON SKU_ATTR_VALUE.SkuID=SKU.SkuID
INNER JOIN Product
ON SKU.ProductID=Product.ProductID
WHERE Product.ProductID=?
Pretty simple. I can run this in the SQLite database browser, replacing the ? with 1, and it returns 18 rows, which is just what it should do. Only 18 rows match the condition. But when I run this in Java, and pass in the value 1, I get 817 values back. And that's not a Cartesian join; there are 864 possible values in SKU_ATTR_VALUE. The results I get back have at least one value for each record in Product too...so I really can't imagine what is happening.
I've been looking at this a while and I'm completely stumped. Googling it doesn't seem to turn anything up. Yes, I'm sure that I'm running the Java query against the same SQLite database as in the SQLite browser.
The name of the SQLite jar is sqlitejdbc-v056.jar. It is based on SQLite 3.6.14.2.
Here is the Java code that sets up the query:
String sql = "SELECT SKU_ATTR_VALUE.*, Product.ProductID " +
"FROM SKU_ATTR_VALUE " +
" INNER JOIN SKU ON SKU_ATTR_VALUE.SkuID=SKU.SkuID " +
" INNER JOIN Product ON SKU.ProductID=Product.ProductID " +
"WHERE Product.ProductID=?";
ps = conn.prepareStatement(sql);
ps.setInt(1, productID);
ResultSet rs = ps.executeQuery();
According to this document section "5.0 Joins" : you can try to rewrite your query like this :
SELECT
SKU_ATTR_VALUE.*,
Product.ProductID
FROM
Product, SKU, SKU_ATTR_VALUE
WHERE
Product.ProductID=?
AND SKU.ProductID=Product.ProductID
AND SKU_ATTR_VALUE.SkuID=SKU.SkuID