I want to insert a Dataframe in a table using ODBC.jl , the table already exists and it seems that i can't use the function ODBC.load with it (even with the append=true).
usually i insert DataFrames with copyIn by loading the dataframe as a csv but with just ODBC it seems i can't do that .
The last thing i found is :
stmt = ODBC.prepare(dsn, "INSERT INTO cool_table VALUES(?, ?, ?)")
for row = 1:size(df, 1)
ODBC.execute!(stmt, [df[row, x] for x = 1:size(df, 2)])
end
but this is line by line , it's incredibly long to insert everything .
I tried also to do it myself like this :
_prepare_field(x::Any) = x
_prepare_field(x::Missing) = ""
_prepare_field(x::AbstractString) = string(''', x, ''')
row_names = join(string.(Tables.columnnames(table)), ",")
row_strings = imap(Tables.eachrow(table)) do row
join((_prepare_field(x) for x in row), ",") * "\n"
end
query = "INSERT INTO $tableName($row_names) VALUES $row_strings"
#debug "Inserting $(nrow(df)) in $tableName)"
DBInterface.execute(db.conn, query)
but it throw me an error because of some "," not at the right place at like col 9232123
which i can't find because i have too many lines , i guess it's the _prepare_field that doesn't cover all possible strings escape but i can't find another way .
Did i miss something and there is a easier way to do it ?
Thank you
I would like to execute a fairly complex SQL statement using SQLite.swift and get the result preferably in an array to use as a data source for a tableview. The statement looks like this:
SELECT defindex, AVG(price) FROM prices WHERE quality = 5 AND price_index != 0 GROUP BY defindex ORDER BY AVG(price) DESC
I was studying the SQLite.swift documentation to ind out how to do it properly, but I couldn't find a way. I could call prepare on the database and iterate through the Statement object, but that wouldn't be optimal performance wise.
Any help would be appreciated.
Most sequences in Swift can be unpacked into an array by simply wrapping the sequence itself in an array:
let stmt = db.prepare(
"SELECT defindex, AVG(price) FROM prices " +
"WHERE quality = 5 AND price_index != 0 " +
"GROUP BY defindex " +
"ORDER BY AVG(price) DESC"
)
let rows = Array(stmt)
Building a data source from this should be relatively straightforward at this point.
If you use the type-safe API, it would look like this:
let query = prices.select(defindex, average(price))
.filter(quality == 5 && price_index != 0)
.group(defindex)
.order(average(price).desc)
let rows = Array(query)
I get the following error when trying to create a default row in the asp.net dropdown: Conversion from string "x" to type 'Integer' is not valid.
CmbSalesAgents is the drop down control.
DefaultSalesAgent is the entity object (has values)
x is a concatenation of a numeric value and a string
**
Dim DefaultSalesAgent = (From o In db.PayoutRegisters
Join s In db.SalesAgents On s.SalesAgentId Equals o.SalesAgentID
Where o.PayoutRegisterID = PayoutRegisterID
Select o.PayoutRegisterID, x = s.CSRName + " (" + o.PaidThruDate.ToString + ")").ToList
If DefaultSalesAgent.Count > 0 Then
CmbSalesAgents.Items.Insert(0, New ListItem(DefaultSalesAgent.Item("x").ToString, PayoutRegisterID))
Else
CmbSalesAgents.Items.Insert(0, New ListItem("Select Sales Agent Payout Register", 0))
End If
Since DefaultSalesAgent is a list object then you should access its items through integer index not a string:
DefaultSalesAgent.Item(integer_index)
If you specifically need to insert the row based off a string value, you can replace
DefaultSalesAgent.Item("x")
With
DefaultSalesAgent.Item(DefaultSalesAgent.FindIndex(x => x.StartsWith("x")));
You can also use contains instead of startswith depending on your needs. Please note this is only if you specifically need to look for strings as it's a lot more expensive than accessing an index in the list.
I need to manage hierarchy data storing in my database. But I have a problem now. Please see my example
I have a table called COMMON.TASK_REL
My second table is called Common. task
I suppose need to sort the task_seq and return a result like below:
Task Name || Task_Seq
Item1 1
..Item1.2 1
...Item1.2.1 1
..Item1.1 2
Here is my query
--Common task SQL modify --
WITH ctLevel
AS
(
SELECT
C_TASK_ID AS Child
,P_Task_ID AS Parent
,common_task.TASK_SEQ AS taskOrder
,1 AS [Level]
,CAST(C_TASK_ID AS VARCHAR(MAX)) AS [Order]
,CAST (Replicate('.', 1) + common_task.TASK_NAME AS VARCHAR(25)) AS [Task_Name]
FROM
[COMMON.TASK_REL] as common_task_rel,
[COMMON.TASK] as common_task
WHERE common_task_rel.C_TASK_ID = common_task.TASK_ID
and common_task.[TASK_TYPE] = 'B' AND common_task.[MODULE_CODE] = 'LWRPT'
AND common_task.[STATUS] <> 'D'
UNION ALL
SELECT
C_TASK_ID AS Child
,P_Task_ID AS Parent
,common_task.TASK_SEQ AS taskOrder
,[Level] + 1 AS [Level]
,[Order] + '.' + CAST(C_TASK_ID AS VARCHAR(MAX)) AS [Order]
,CAST (Replicate('.', [Level] + 1) + common_task.TASK_NAME AS VARCHAR(25)) AS [Task_Name]
FROM [COMMON.TASK_REL] as common_task_rel
INNER JOIN ctLevel
ON ( P_Task_ID = Child ) , [COMMON.TASK] as common_task
WHERE common_task_rel.C_TASK_ID = common_task.TASK_ID
and common_task.[TASK_TYPE] = 'B' AND common_task.[MODULE_CODE] = 'LWRPT'
AND common_task.[STATUS] <> 'D'
)
-- Viewing Data
SELECT Child ,Parent ,taskOrder,Level,[Order],Task_Name
FROM ctLevel
GROUP BY Child ,Parent ,taskOrder,Level,[Order],Task_Name
order by [Order];
GO
But my result returns duplicated rows:
Anyone can help me correct my query? Thanks
I believe that your duplicates are coming from your root/anchor query. You should add the following to that query:
AND Task_Seq = 0
Basically, you only want the root to be set up as the beginning of the tree. 301|300 should not be picked up until the recursion section (the part after union all)
If that does not make sense, then I can repaste your query with the modification, but that seemed unnecessary for a small change.
I have a table which contains a phone number column. There is no restrictions on how to enter the phone numbers. Currently the phone numbers are in the following format
123-456-7890
(123)-456-7890
1234567890
I would like to update the table and bring all phone numbers in 123-456-7890 format. I have over 20k records. Can I do that using SQL Query or I have to use regular expression in ASP or PHP?
Edit: Note best answer is for modified question, with phone number (123)-456-78790 changed to (123)456-7890
If they are strictly in one of those 3 formats, you can do it in SQL easy enough by using SUBSTRING and testing the LEN of each item.
If there are other formats, I'd suggest doing this in a language that is better at text-manipulation, such as .net.
Edit to add:
Given your comment that it'll only be those 3 formats for now, you can do this:
declare #t table (x varchar(20))
insert into #t
select '123-456-7890'
union select '(123)456-7890'
union select '1234567890'
select
case
when len(x) = 10 then
substring(x, 1, 3) + '-' + substring(x, 4, 3) + '-' + substring(x, 7, 4)
when len(x) = 13 then
substring(x, 2, 3) + '-' + substring(x, 6, 8)
else x
end
from #t
This will work:
First replace the parentheses and hyphens, then add them back in.
DECLARE #Number varchar(25)
SELECT #Number = '(123)-456-7890'
SELECT SUBSTRING(REPLACE(REPLACE(REPLACE(#Number, '(', ''), ')', ''), '-', ''), 1, 3)
+ '-'
+ SUBSTRING(REPLACE(REPLACE(REPLACE(#Number, '(', ''), ')', ''), '-', ''), 4, 3)
+ '-'
+ SUBSTRING(REPLACE(REPLACE(REPLACE(#Number, '(', ''), ')', ''), '-', ''), 7, 4)
Note
You could create a scalar function to replace all the hyphens and parentheses... It would be more readable then:
DECLARE #Number varchar(25)
SELECT #Number = '(123)-456-7890'
SELECT SUBSTRING(StripCharacters(#Number), 1, 3)
+ '-'
+ SUBSTRING(StripCharacters(#Number), 4, 3)
+ '-'
+ SUBSTRING(StripCharacters(#Number), 7, 4)
Succinct and without temp tables:
UPDATE Phones
SET phone =
SUBSTRING(REPLACE(REPLACE(REPLACE(phone,'-',''),')',''),'(',''),1,3) + '-'
+ SUBSTRING(REPLACE(REPLACE(REPLACE(phone,'-',''),')',''),'(',''),4,3) + '-'
+ SUBSTRING(REPLACE(REPLACE(REPLACE(phone,'-',''),')',''),'(',''),7,4)
Here is a great example:
Shows how to create User Defined Functions, custom formatting function for telephone numbers in TSQL
I would load every phone number and strip them.
So remove all periods, commas, hyphens, - basically anything that isn't a number.
Then reinsert them in the format you're looking for.
you can do this through a query, or server side language.
If you only have 20K records then just go with whatever is easier for you. Personally, I would pull all the data and then reinsert it using a server side language. PHP, ASP, or SQL it doesn't really matter if this is a one time thing. Just be sure to set up some formatting restrictions on new inserts though.
Look at this quick example:
CREATE TABLE #temp
(
phonenumber VARCHAR(15)
)
INSERT INTO #temp
( phonenumber )
VALUES ( '555-578-5899'
INSERT INTO #temp
( phonenumber )
VALUES ( '(555)-896-3269' )
INSERT INTO #temp
( phonenumber )
VALUES ( '123-456-2129')
update #temp
set phonenumber=replace(phonenumber,'(','')
update #temp
set phonenumber=replace(phonenumber,')','')
update #temp
set phonenumber=replace(phonenumber,'-','')
-- That will eliminate all (,- and ) from the table
update #temp
set phonenumber=left(phonenumber,3)+'-'+substring(phonenumber,4,3)
+'-'+right(phonenumber,4)
SELECT * FROM #temp
DROP TABLE #temp