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 have a sqlite text column with comma separated integer like 3,899,550. How can I use this value as an integer? I want to filter by values greater than 1million.
select * from table_t where some_func(comma_sep_column) > 1000000?
Here is one option:
SELECT CAST(REPLACE('1,234,567', ',', '') AS INTEGER);
The REPLACE function removes the ',' and the CAST function converts to an integer.
Your code would then be:
SELECT * FROM tbl WHERE CAST(REPLACE(comma_sep_column, ',', '') AS INTEGER) > 1000000;
Im using Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
We replaced LISTAGG() with XMLAGG() to avoid concatenation error.
when i check the lenght of charecters from both of the fuction output, XMLAGG() giving an extra char in length.
Could you please suggest me how can i overcome this issue.
Please find the below sql and out put
XMLAGG():
SELECT TO_CHAR (
SUBSTR (
XMLAGG (XMLELEMENT (e, table_name, CHR (13)).EXTRACT (
'//text()') ORDER BY tablespace_name).GetClobVal (),
1,
2000))
AS str_concate,
LENGTH (
TO_CHAR (
SUBSTR (
XMLAGG (XMLELEMENT (e, table_name, CHR (13)).EXTRACT (
'//text()') ORDER BY tablespace_name).GetClobVal (),
1,
2000)))
AS str_length
FROM all_tables
WHERE table_name = 'TEST_LOAD
OUTPUT:
STR_CONCATE STR_LENGTH
TEST_LOAD TEST_LOAD 26
LISTAGG()
SELECT LISTAGG (SUBSTR (table_name, 1, 2000), CHR (13))
WITHIN GROUP (ORDER BY tablespace_name)
AS str_concate,
LENGTH (
LISTAGG (SUBSTR (table_name, 1, 2000), CHR (13))
WITHIN GROUP (ORDER BY tablespace_name))
AS str_length
FROM all_tables
WHERE table_name = 'TEST_LOAD';
OUTPUT:
STR_CONCATE STR_LENGTH
TEST_LOAD TEST_LOAD 25
In case of XMLELEMENT, you actually create node of XML tree with two children: table_name and CHR(13). (May be it finally looks like single node since both are texts but it is not important.) It is expansion of value_expr nonterminal. The substantial thing is the node is not aware of other nodes and CHR(13) is added to every node as its suffix or, in other words, terminator.
In case of LISTAGG, you describe aggregation of multiple elements. In this case, your CHR(13) serves as delimiter (see syntax diagram) which is put between elements. It is separator rather than terminator.
Since XMLAGG does not suffer with 4000 char limit, I usually prefer XMLAGG.
If separator is needed, I recommend to prepend it before each value and cut first occurence using substr. Appending after is possible but makes expression harder.
substr(
xmlagg(
xmlelement(e, ', ' || table_name).extract('//text()')
order by tablespace_name
).getclobval(),
3 -- length(', ')+1
)
I have a table in sqlite db called [tblbook] with a column [authors]. What I am trying to do in the sql is to split the author values to firstname and the lastname and sort it on lastname. I did find this great code:
SELECT substr(BookAuthor, 1, NULLIF(CHARINDEX(' ', BookAuthor) - 1, -1)) AS [FirstName],
substr(BookAuthor, CHARINDEX(' ', BookAuthor) + 1, LEN(BookAuthor)) AS [LastName]
FROM tblBook where _id=3
It works perfectly on MSSQL but sqlite doesn't have the charindex function hence it fails.
Could anyone please be kind and advise me what should be the best approach to achieve this.
Another way (a little shorter) to write this would be
SELECT
substr(BookAuthor, 1, instr(BookAuthor, ' ') - 1) AS first_name,
substr(BookAuthor, instr(BookAuthor, ' ') + 1) AS last_name
FROM tblBook where id=3
ORDER BY last_name
This would apply for version 3.7.15 and beyond.
Unfortunately this functionality is missing from SQLite:
http://www.sqlite.org/lang_corefunc.html
Index of substring in SQLite3?
Maybe you can feed your custom string position function to SQLite using http://www.sqlite.org/c3ref/create_function.html
But if you really need it, there is a complex, ineffective workaround:
http://sqlfiddle.com/#!7/e03a4/3
1: create a numbers table/view
2: join authors to numbers table, and choose the MIN position of the space
3: now you can split the names
SELECT
substr( name, 1, pos-1) AS first_name,
substr( name, pos+1) AS last_name
FROM (
SELECT
author.name,
numbers.x AS pos
FROM author
INNER JOIN numbers
WHERE substr( author.name, numbers.x, 1) = ' '
GROUP BY author.name
) AS a
ORDER BY last_name;
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