I have a SQL query:
update SCOTT.GLOBAL set DAY_LIGHT_SAVING_STARTS=TO_DATE('03/31/2013 02:00:00', 'MM/DD/YYYY HH24:MI:SS'), DAY_LIGHT_SAVING_ENDS=TO_DATE('10/27/2011 02:00:00', 'MM/DD/YYYY HH24:MI:SS') where zone='GMT';
I want to replace every occurance of TO_DATE with a random number/string and also want the correcponding TO_DATE and random number/string to be saved in a file.
For example:
update SCOTT.GLOBAL set DAY_LIGHT_SAVING_STARTS=abc, DAY_LIGHT_SAVING_ENDS=pqr where zone='GMT';
File:
TO_DATE('03/31/2013 02:00:00', 'MM/DD/YYYY HH24:MI:SS')~~~~abc
TO_DATE('10/27/2011 02:00:00', 'MM/DD/YYYY HH24:MI:SS')~~~~pqr
How can I achieve this with awk/sed/perl?
I have certainly tried something, though did not share with SO here. Apologies. Here is what I have tried:
perl -p -i -e "s/TO_DATE(.*?)\)/abc/g" my.out
This replaces the occurances of TO_DATE but I cannot figure how I can generate separate random numbers in same line for two different occurances of TO_DATE, and save them to the file along with the corresponding TO_DATE clause.
If I understood well your needs you can try in bash something like bellow:
while read x; do
while [[ $x =~ TO_DATE\([^\)]+\) ]]; do
rand=$(dd if=/dev/urandom bs=3 count=1 2>/dev/null|base64)
x=${x/$BASH_REMATCH/$rand}
done
echo $x
done<<XXX
update SCOTT.GLOBAL set DAY_LIGHT_SAVING_STARTS=TO_DATE('03/31/2013 02:00:00', 'MM/DD/YYYY HH24:MI:SS'), DAY_LIGHT_SAVING_ENDS=TO_DATE('10/27/2011 02:00:00', 'MM/DD/YYYY HH24:MI:SS') where zone='GMT';
XXX
Output
update SCOTT.GLOBAL set DAY_LIGHT_SAVING_STARTS=YsuW, DAY_LIGHT_SAVING_ENDS=5Vve where zone='GMT';
This read every lines from a file (which is replaced by a here-is-the-document here). If the line matches with the TO_DATE\([^\)]+\) pattern it creates a semi-random string from the matching proportion reading /dev/urandom and replaces the found string with this encrypted string. Because of base64 the bs in dd always should be multiple of 3 to avoid the = character from the end. It only works if the + and / is acceptable in the random string.
Related
I try to change the date format in a quickpart database function.
The format is in American (mm/d/yyyy) but i want to change in the French format (dd.MM.yyyy).
This is my code :
DATABASE \d "C:\Users\taagede1\Dropbox\Samaritains\Soldes et
indemnités\2018\Total soldes.xlsx" \c
"Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data
Source=C:\Users\taagede1\Dropbox\Samaritains\Soldes et
indemnités\2018\Total soldes.xlsx;Mode=Read;Extended
Properties=\"HDR=YES;IMEX=1;\";Jet OLEDB:System database=\"\";Jet
OLEDB:Registry Path=\"\";Jet OLEDB:Engine Type=37;Jet OLEDB:Database
Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global
Bulk Transactions=1;Jet OLEDB:New Database Password=\"\";Jet
OLEDB:Create System Database=False;Jet OLEDB:Encrypt
Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet
OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet
OLEDB:Support Complex Data=False;Jet OLEDB:Bypass UserInfo
Validation=False;Jet OLEDB:Limited DB Caching=False;Jet OLEDB:Bypass
ChoiceField Validation=False" \s "SELECT Quoi, Date , Heure
Début, Heure Fin, Total FROM Engagements$ WHERE ((NomPrenom =
'AubortLoic') AND (Payé IS NULL )) ORDER BY Date" \l "26" \b "191"
\h
This is the result:
I have tried to add this:
{ DATABASE [\# "dd.MM.yyyy"] \* MERGEFORMAT }
But i have a very ugly result (all buggy)
The OLEDB driver for Excel (and Access - it's the same one) supports a limited number of functions that can be used on the data via the Select query, among them Format. It's similar, but not identical to the VBA function of the same name.
In my test the following Select phrase worked (extracted from the Database field code for better visibility):
\s "SELECT Quoi, Format([Date], 'dd.MM.yyyy') AS FrDate, Heure
Début, Heure Fin, Total FROM Engagements$ WHERE ((NomPrenom = 'AubortLoic') AND (Payé IS NULL )) ORDER BY Date
Note that the date format is in single, not double quotes. You can use anything for the alias (the column header), except another field name. So it can't be Date if that's the field name in the data source. It could be Le Date, but in this case, due to the spaces, it would have to be in square brackets: [Le Date].
I need to convert some strings with this format:
B12F34
to something like that:
Building 12 - Floor 34
but I have to add a value, say 10, to the second capture group so the new string would be as:
Building 12 - Floor 44
I can use this postgres sentence to get almost everything done, but I don't know how to add the value to the second capture group.
SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', 'Building \1 - Floor \2', 'g');
I have been searching for a way to add a value to \2 but all I have found is that I can use 'E'-modifier, and then \1 and \2 need to be \\1 and \\2:
SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', E'Building \\1 - Floor \\2', 'g')
I need some sentence like this one:
SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', E'Building \\1 - Floor \\2+10', 'g')
to get ........ Floor 44 instead of ........ Floor 34+10
You can not do this in regexp alone because regexp does not support math on captured groups even if they are all numeric characters. So you have to get the group that represents the floor number, do the math and splice it back in:
SELECT regexp_replace('B12F34', 'B(\d+)F(\d+)', 'Building \1 - Floor ') ||
((regexp_matches('B12F34', '[0-9]+$'))[1]::int + 10)::text;
Not very efficient because of the two regexp calls. Another option is to just get the two numbers in a sub-query and assemble the string in the main query:
SELECT format('Building %L - Floor %L', m.num[1], (m.num[2])::int + 10)
FROM (
SELECT regexp_matches('B12F34', '[0-9]+', 'g') AS num) m;
I have a var: acc_date with type date.
It takes its value from a cursor and when I insert its value to logger table as:
insert into logger values(1,acc_date);
the out put when a select it from logger is
1 01-JAN-10
but when i use it to compare with another Date value in another cursor as
OPEN c_get_date_id
for 'SELECT Date_D.DATEKEY from Date_D where Date_D.DATEVALUE='||acc_date;
EXIT WHEN c_get_date_id%NOTFOUND;
FETCH c_get_date_id
INTO date_id;
insert into logger values (1,'Now with date_id'||date_id);
CLOSE c_get_date_id;
an error occurs:
Error report:
ORA-00904: "JAN": invalid identifier
ORA-06512: at "HW.FILLFACT", line 82
ORA-06512: at line 1
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
strong text
You need at least add some quotes around the date:
....' where Date_D.DATEVALUE='''||acc_date||'''';
Double apostrophes within a string will be concatenated to a single apostrophe, so that the expression becomes
where Date_D.DATEVALUE='....';
In order to make the thing more foolprof, I'd also add a specific to_date:
.... ' where Date_D.DATEVALUE=to_date(''' || acc_date || ', ''dd-mon-yy'')';
At the moment your dynamic query is being interpreted as:
SELECT Date_D.DATEKEY from Date_D where Date_D.DATEVALUE=01-JAN-10
The error is because string representation of the date isn't being quoted, so it's seeing JAN as an identifier - and nothing matches that name. You could enclose the date value in quotes:
open c_get_date_id
for 'SELECT Date_D.DATEKEY from Date_D where Date_D.DATEVALUE='''||acc_date||'''';
But you're treating the date as a string, and forcing conversion of all your table values to strings to be compared, using your session's NLS_DATE_FORMAT. It would be better to compare it as a date (although this somewhat assumes all your values have the time portion set to midnight):
open c_get_date_id
for select date_d.datekey from date_d where date_d.datevalue = acc_date;
Your exit is in the wrong place though, and you aren't looping, so maybe you want:
open c_get_date_id
for select date_d.datekey from date_d where date_d.datevalue = acc_date;
loop
fetch c_get_date_id into date_id;
exit when c_get_date_id%notfound;
insert into logger values (1, 'Now with date_id'||date_id);
end loop;
close c_get_date_id;
If you only have one value in the first place though, you probably don't want a loop or cursor at all, and could do a simple select ... into instead:
select date_d.datekey into date_id from date_d
where date_d.datevalue = acc_date;
insert into logger values (1, 'Now with date_id'||date_id);
Though of course that would error if you had no matching date in your table, or more than one, and you'd need to deal with that - but then I guess you'd want to anyway.
I have a file content like this
select b.id as cli_id,b.login as cli_login, b.pname as cli_name,
b.cname as cli_company, b.phone as cli_phone, b.email as cli_email,
(select (value / 1048576) from Limits where limit_name='disk_space'
and id=b.limits_id) as Client_Package, b.cr_date, (select
FROM_UNIXTIME(value,"%Y-%m-%d") from Limits where
limit_name='expiration' and id=b.limits_id) as Client_expire,
If(b.status=0,'Active','Inactive') as Cli_Status, a.name as dom_name,
If(a.status=0,'Active','Inactive') as Dom_Package, a.cr_date as
dom_create, (select FROM_UNIXTIME(value,"%Y-%m-%d") from Limits where
limit_name='expiration' and id=a.limits_id) as dom_expire, (select
(value / 1048576) from Limits where limit_name='disk_space' and
id=a.limits_id) as Dom_Package, round((a.real_size / 1048576)) as
Dom_usage from domains a, clients b where (select
FROM_UNIXTIME(value,"%Y-%m-%d") from Limits where
limit_name='expiration' and id=a.limits_id and
(FROM_UNIXTIME(value,"%Y-%m-%d") between '2011-08-01' and
'2011-12-01') ) and a.cl_id=b.id group by a.id;
this all comes in a single line
in that i want to replace the date part alone in this format
between '2011-08-01' and '2011-12-01'
The script runs every friday , suppose if i run this on 10th month means.
the script need to change the value in the file like this
between '2011-09-01' and '2012-01-01'
every time the month alone need to change in this format
between 'current month -1month' and 'current month + 3 months'
sed -i 's/between '2011-08-01' and '2011-12-01'/'between '$(date --date="- 1 month" +%Y-%m)-01' and '$(date --date="+ 3 months" +%Y-%m)-01'/g file1
in this code iam trying to find and replace
but it shows this error
sed: -e expression #1, char 44: unterminated `s' command
What mistake iam doing can any 1 explain?
The expression isn't properly quoted. You start with 's/... but end with ... /g. No quote there. This is what I ran and it worked fine:
sed -i "s/between '[0-9-]*' and '[0-9-]*'/between '$(date --date'-1month' +%Y-%m-01)' and '$(date --date'+3months' +%Y-%m-01)'/g" file1
I am the struggling with the following command. In reality, it is to be executed as a SQL statement. I am printing out the statement below using disp command.
Datevar = datestr(date,'mm/dd/yyyy') ; % 07/25/2011
% Required command: execute SQLname #startdate = '7/25/2011'
% My current command:
disp([...
'execute SQLname ' ...
'#startdate = ' ''' Datevar ''' ...
])
I have tried many combinations but I am not able to hit this string right: #startdate = '7/25/2011'. Thanks!
Misplaced quote, at least in the example code you posted. That third line of the disp call is concatenating two separate strings, and the second one contains a literal "Datevar". You want this, which will concatenate the contents of the variable named Datevar.
sql = [...
'execute SQLname ' ...
'#startdate = ''' Datevar '''' ...
];
disp(sql);
IMHO, short queries like these are more readable if you construct them with sprintf, because you don't have to differentiate between internal quotes and delimiting quotes.
sql = sprintf('execute SQLname #startdate = ''%s''', Datevar);
If you include an example of the exact output you are getting, it's easier to diagnose problems like this.
It seems like you are do not want the leading zeroes provided by datestr. There are no date specifiers for returning non-padded day and month values. You can create the string you want by using DATEVEC and SPRINTF like this:
>> date = datevec('2011/07/25');
>> sprintf('execute SQLname #startdate = ''%u/%u/%u''', date([2 3 1]))
ans =
execute SQLname #startdate = '7/25/2011'