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
In SSRS, how could I create a field, similar to a "comments" field in a record that would list a set of strings, conditionally, depending on how a set of questions on a VB.NET web form are answered?
Say, 5 questions have RadioButtonLists with "Y", "N", and "N/A" as the three answer items. The answers go into a SQL (Server 2008R2) table as a "Review" record.
Question #2 and #4 are answered "N", the rest are answered "Y" or "N/A."
I'm trying to get that comments field in SSRS to be populated with similar to the following:
Q2: 1100 - No Documentation in file.
Q4: 4100 - No Case note.
In SQL I've tried declaring a variable to hold a string and concatenating question string values based on field contents. I tried nested IIF expressions in the SSRS column, but I can't figure out how to do what you can do in C# or VB like string1 = string1 + string2 or string1 += string2, in order to selectively add the strings to a variable to then display.
I need an SSRS report for each of the forms and each record needs that comments field listing the "Findings" or questions with "N" answers.
After your comments, I think I understand better. You want a comments column with the No values concatenated together with line breaks. You will have to adjust the below to match your tables but hopefully this helps.
select [AssignedOneActivity],
Comments = STUFF( (
SELECT char(10) + char(13) + a2.[AssignedOneActivity] + ': ' + a2.answer
FROM dbo.[WIA_Youth] a2
where a.ReviewID = a2.ReviewID
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(max)'), 1, 2, ''
)
from dbo.[WIA_Youth] a
However, I now read that your storing your Q+A in columns. so maybe this would be better:
select
reviewid,
Comments =
case when [AssignedOneActivity] = 'N' then 'Q1: No answers' + char(10) + char(13) else '' end +
case when [AssignedTwoActivity] = 'N' then 'Q2: No answers' + char(10) + char(13) else '' end +
case when [AssignedThreeActivity] = 'N' then 'Q3: No answers' + char(10) + char(13) else '' end
from dbo.wia_youth
I have phone number field in database. It has already data.
I want to change my phone number format to "XXX-XXX-XXXX"
Current database has no any phone format.
So there may be garbage data. I have already applied validation for new records but now I want to change my existing data also.
Is there any specific way through that I can change my existing data. And make all phone numbers to follow this format.
Please advice.
Create function to remove the non-numeric data and do the formatting
CREATE FUNCTION [UDF_STRIP_NONNUMERIC_DATA](#str VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
WHILE Patindex('%[^0-9]%', #str) > 0
BEGIN
SET #str = Stuff(#str, Patindex('%[^0-9]%', #str), 1, '')
END
RETURN #str
END
You can use STUFF function to inset the - between phone number
Select left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](Phone),4,0,'-'),8,0,'-'),12)
From yourtable
If you are using SQL SERVER 2012+ use can use FORMAT function (thanks to LukStorms, who mentioned it in comment)
SELECT Format(Cast(dbo.[Udf_strip_nonnumeric_data](Phone) AS BIGINT), '###-###-####')
FROM yourtable
To update
Update yourtable
SET phone = left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](Phone),4,0,'-'),8,0,'-'),12)
Demo
declare #str varchar(100)= '9225-123-4567'
select left(Stuff(Stuff(dbo.[UDF_STRIP_NONNUMERIC_DATA](#str),4,0,'-'),8,0,'-'),12)
Result : 922-512-3456
declare #phone varchar(24)
set #phone = '(334)789-4532'
--set #phone = '314789-4532'
--set #phone = '3457894532'
--set #phone = '534-789-4532'
SELECT
LEFT(N,3) + '-' + SUBSTRING(N,4,3) + '-' + RIGHT(N,4)
FROM
(SELECT CAST(CAST((
SELECT SUBSTRING(#phone, Number, 1)
FROM master..spt_values
WHERE Type='p' AND Number <= LEN(#phone) AND
SUBSTRING(#phone, Number, 1) LIKE '[0-9]' FOR XML Path(''))
AS xml) AS varchar(MAX)) as N) as N
Ok, to replace all non-numeric characters, look at this.
Here is a sample script (copied from that link) to show you how it works (You'll need to modify this to fit your table name and column names:
-- Step 1: creates table to use to hold every char in every phone number
if object_id('dbo.tally') is not null drop table dbo.tally
select top 10000 --change to fit max length of phone number
identity(int,1,1) as n
into dbo.tally
from master.dbo.syscolumns sc1,
master.dbo.syscolumns sc2
-- add pk to maximize performance
alter table dbo.tally
add constraint pk_tally_n
primary key clustered (n) with fillfactor = 100
-- Step 2: Create temporary table holding three bad phone numbers
declare #phonetable table
(uniqueid int identity(1,1),
phone_number varchar(500))
insert into #phonetable (phone_number)
select '01234-567-890' union
select '012345 6789ext' union
select 'n/a' union select '...12345.....';
-- Step 3: identify, for every character, whether it is a number or not,
and remove the non-numeric ones
with cte (uniqueid, phone_number, goodchar, badchar) as
( select uniqueid, phone_number,
case when substring(phone_number,N,1) not like '%[^0-9]%'
then substring(phone_number,N,1) end as goodchar,
case when substring(phone_number,N,1) like '%[^0-9]%'
then substring(phone_number,N,1) end as badchar
from #phonetable , Tally
where phone_number like '%[^0-9]%' and N <= len(phone_number) )
select distinct phone_number,
isnull( stuff (
( SELECT '' + goodchar
FROM cte t1
where t1.UniqueID = t2.UniqueID
FOR XML PATH ( '' ) ) , 1 , 0 , '' ) ,'')
as clean_phone_number from cte t2
to display the numbers with formatting, just extract the appropriate pieces and re-concatenate them with the dashes.
Select case len(phone)
When 10 then left(phone, 3) + '-' +
substring(phone, 4,3) + '-' +
substring(phone, 7,4)`
When 7 then left(phone, 3) + '-' +
substring(phone, 4,4)
Else '' end
To create a computed column
Alter table Add Column FormattedPhone as
case len(phone)
When 10 then left(phone, 3) + '-' +
substring(phone, 4,3) + '-' +
substring(phone, 7,4)`
When 7 then left(phone, 3) + '-' +
substring(phone, 4,4)
Else '' end
If you don't mind a UDF
Select [dbo].[udf-Str-Format-Phone]('334)789-4532')
Returns
334-789-4532
The UDF
CREATE FUNCTION [dbo].[udf-Str-Format-Phone] (#S varchar(max))
Returns varchar(25)
AS
Begin
Declare #Return varchar(25)
;with cte0(N) As (Select 1 From (Values(1),(1),(1),(1),(1)) N(N))
, cteN(N) As (Select Top (Len(#S)) Row_Number() over (Order By (Select NULL)) From cte0 N1, cte0 N2)
, cteS(S) As (Select Substring(#S,N,1) From cteN Where Substring(#S, N, 1) LIKE '[0-9]' FOR XML Path(''))
Select #Return = IIf(Len(S)>=10,Stuff(stuff(S,4,0,'-'),8,0,'-'),Stuff(S,4,0,'-')) From cteS
Return #Return
End
-- Syntax : Select [dbo].[udf-Str-Format-Phone]('(334)789-4532') -- Returns 334-789-4532
-- Syntax : Select [dbo].[udf-Str-Format-Phone]('Phone:7894532') -- Returns 789-4532
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;