Script to generate data, SQL oracle 10g - sql

I'm trying to build a script that insert random datas into my table.
My actual script looks like that :
INSERT INTO Utilisateurs (id_utilisateur, Uti_nom, Uti_prenom, Uti_role, Uti_mdp, Uti_Statut)
SELECT
-- here to input the id (number that increment each time)
dbms_random.string('A', trunc(dbms_random.value(5, 50))), -- data for uti_nom
dbms_random.string('A', trunc(dbms_random.value(5, 100))), -- data for uti_prenom
-- randomly get 'Administrateur' or 'Utilisateur'
dbms_random.string('X', 10), -- data for uti_mdp
trunc(dbms_random.value(0, 1)) -- data for uti_status
FROM dual
CONNECT BY LEVEL < 100;
So if someone can help me to get the both comment line...
There's a sample, but what i really need it's the ID that increments and Uti_role (Administrateur/Utilisateur) the others fields can be generated and looks like "dsjhadakj"
id_utilisateur Uti_nom Uti_prenom Uti_role Uti_mdp Uti_Statut
d--------+---------+---------+---------+---------+---------+---------+---------+
1 Elche Marco Administrateur Haj432Hgn 1
2 Babo Jules Utilisateur Haj432Hgn 0
3 Ghale Alex Administrateur Haj432Hgn 1

For self-incremental ID you can use LEVEL
For uti_role something like this:
CASE WHEN dbms_random.value(0, 1) > 0.5 THEN 'Administrateur' ELSE 'Utilisateur' END
Here's SQL Fiddle for just the SELECT part.

Related

How to insert values from a subquery in merge sentence

I want to insert into a merge statement of a stored procedure at ORACLE a value that comes from a subquery. How can I do that? This is what I design but it doesn't work.
CREATE OR REPLACE PROCEDURE P_FORMULARIO
IS
BEGIN
MERGE INTO HT_FORMULARIO d
USING
(SELECT id, METODO_ID, TIPO_ID, DEPARTAMENTO_ID, EQUIPAMEINTO_ID, FECHAINICIO
FROM ODS_FORMULARIO) o
ON (d.ID_CAMPO = o.id)
WHEN MATCHED THEN
UPDATE SET d.SK_METODO_MUEST = o.METODO_ID,
d.SK_TIPO_MUESTRA = o.TIPO_ID,
d.SK_DEPARTAMENTO = o.DEPARTAMENTO_ID,
d.SK_EQUIPAMIENTO = o.EQUIPAMEINTO_ID
WHEN NOT MATCHED THEN
INSERT (ID_CAMPO, SK_METODO_MUEST, SK_TIPO_MUESTRA, SK_DEPARTAMENTO, SK_EQUIPAMIENTO)
VALUES (o.id, o.METODO_ID, o.TIPO_ID,o.DEPARTAMENTO_ID, o.EQUIPAMEINTO_ID,
(select SK_FECHA from dt_fecha where mes = MONTH( o.FECHAINICIO) and anio = YEAR(o.FECHAINICIO));
COMMIT;
END P_EQUIPAMIENTO;
I don't know if that is possible, thanks for the help.
There are some things wrong in your procedure
The subselect below the insert does not make any sense, as you have only five fields in the insert clause and five values in the values section.
You are getting all the records from ODS_FORMULARIO that are matching with the target table HT_FORMULARIO based on the ID, then use that part to get the values of year and month there.
It is not clear whether you want to do with year and month. Those are java in-build funtions, not SQL.
The insert misses a field.
Your functions don't work in SQL:
SQL> select month(sysdate) from dual ;
select month(sysdate) from dual
*
ERROR at line 1:
ORA-00904: "MONTH": invalid identifier
SQL> select year(sysdate) from dual ;
select year(sysdate) from dual
*
ERROR at line 1:
ORA-00904: "YEAR": invalid identifier
Keep in mind the way to get this year and month from your dt_fecha table, some options you might have for that are:
SQL> select to_char(sysdate,'Month') from dual ;
TO_CHAR(SYSDATE,'MONTH')
------------------------------------
October
SQL> select to_char(sysdate,'YYYY') from dual ;
TO_C
----
2021
SQL> select extract(month from sysdate) from dual ;
EXTRACT(MONTHFROMSYSDATE)
-------------------------
10
SQL> select extract(year from sysdate) from dual ;
EXTRACT(YEARFROMSYSDATE)
------------------------
2021
Then you have the column MES in the table DT_FECHA. If you have the month store with the name, you need to use NLS_LANGUAGE to get the right name according to your language. Example, in German
SQL> select TO_CHAR(SYSDATE,'fmDay, DD Month YYYY', 'NLS_DATE_LANGUAGE=''GERMAN''') from dual;
TO_CHAR(SYSDATE,'FMDAY,DDMONTHYYYY','NLS_DATE_LANGUAGE=''GERMAN''')
--------------------------------------------------------------------------------
Samstag, 16 Oktober 2021
Having say that, you want to refactor the merge and use a join in the source part of the statement to get there the sk_fecha value.
Important: Remember that I am assuming some things, like the month is stored in Spanish but not in uppercase. If it is stored in uppercase, use the function upper before to_char. If it is in another language, use the proper nls_language. If the month is stored as a number, then you can use to_char with 'MM' or extract as in my example above
CREATE OR REPLACE PROCEDURE P_FORMULARIO
IS
begin
MERGE INTO HT_FORMULARIO d
USING
(SELECT
odsf.id,
odsf.METODO_ID,
odsf.TIPO_ID,
odsf.DEPARTAMENTO_ID,
odsf.EQUIPAMEINTO_ID,
odsf.FECHAINICIO,
to_char(odsf.FECHAINICIO,'Month', 'NLS_DATE_LANGUAGE=''SPANISH''') as Month,
to_char(odsf.FECHAINICIO,'YYYY') as Year ,
dtf.sk_fecha
FROM ODS_FORMULARIO odsf
join dt_fecha dft on dtf.mes = odsf.mes and dtf.anio = odsf.year ) o
ON (d.ID_CAMPO = o.id)
WHEN MATCHED THEN
UPDATE SET d.SK_METODO_MUEST = o.METODO_ID,
d.SK_TIPO_MUESTRA = o.TIPO_ID,
d.SK_DEPARTAMENTO = o.DEPARTAMENTO_ID,
d.SK_EQUIPAMIENTO = o.EQUIPAMEINTO_ID
WHEN NOT MATCHED THEN
INSERT (ID_CAMPO, SK_METODO_MUEST, SK_TIPO_MUESTRA, SK_DEPARTAMENTO, SK_EQUIPAMIENTO , --a field here is missing--)
VALUES (o.id, o.METODO_ID, o.TIPO_ID,o.DEPARTAMENTO_ID, o.EQUIPAMEINTO_ID, o.SK_FECHA );
COMMIT;
END P_EQUIPAMIENTO;

Creating Dynamic Dates as Variable (Column Names) in SQL

First, I have read about similar posts and have read the comments that this isn't an ideal solution and I get it but the boss (ie client) wants it this way. The parameters are as follows (for various reasons too bizarre to go into but trust me):
1. SQL Server Mgmt Studio 2016
2. NO parameters or pass throughs or temp tables. All has to be within contained code.
So here we go:
I need to create column headings that reflect dates:
1. Current date
2. Most recent quarter end prior to current date
3. Most recent quarter end prior to #2
4. Most recent quarter end prior to #3
5. Most recent quarter end prior to #4
6. Most recent quarter end prior to #5
So if using today's date, my column names would be as follows
12/18/2016 9/30/2016 6/30/2016 3/31/2016 12/31/2016 9/30/2015
I can easily do it in SAS but can't in SQL given the requirements stated above.
Help please with same code.
Thank you
Paula
Seems like a long way to go for something which really belongs in the presentation layer. That said, consider the following:
Let's assume you maintain a naming convention for your calculated fields, for example [CurrentDay], [QtrMinus1], [QtrMinus2], [QtrMinus3], [QtrMinus4],[QtrMinus5]. Then we can wrap your complicated query in some dynamic SQL.
Just as an illustration, let's assume your current query results looks like this
After the "wrap", the results will then look like so:
The code - Since you did NOT exclude Dynamic SQL.
Declare #S varchar(max)='
Select [CustName]
,['+convert(varchar(10),GetDate(),101)+'] = [CurrentDay]
,['+Convert(varchar(10),EOMonth(DateFromParts(Year(DateAdd(QQ,-1,GetDate())),DatePart(QQ,DateAdd(QQ,-1,GetDate()))*3,1)),101)+'] = [QtrMinus1]
,['+Convert(varchar(10),EOMonth(DateFromParts(Year(DateAdd(QQ,-2,GetDate())),DatePart(QQ,DateAdd(QQ,-2,GetDate()))*3,1)),101)+'] = [QtrMinus2]
,['+Convert(varchar(10),EOMonth(DateFromParts(Year(DateAdd(QQ,-3,GetDate())),DatePart(QQ,DateAdd(QQ,-3,GetDate()))*3,1)),101)+'] = [QtrMinus3]
,['+Convert(varchar(10),EOMonth(DateFromParts(Year(DateAdd(QQ,-4,GetDate())),DatePart(QQ,DateAdd(QQ,-4,GetDate()))*3,1)),101)+'] = [QtrMinus4]
,['+Convert(varchar(10),EOMonth(DateFromParts(Year(DateAdd(QQ,-5,GetDate())),DatePart(QQ,DateAdd(QQ,-5,GetDate()))*3,1)),101)+'] = [QtrMinus5]
From (
-- Your Complicated Query --
Select * from YourTable
) A
'
Exec(#S)
If it helps the visualization, the generated SQL is as follows:
Select [CustName]
,[12/18/2016] = [CurrentDay]
,[09/30/2016] = [QtrMinus1]
,[06/30/2016] = [QtrMinus2]
,[03/31/2016] = [QtrMinus3]
,[12/31/2015] = [QtrMinus4]
,[09/30/2015] = [QtrMinus5]
From (
-- Your Complicated Query --
Select * from YourTable
) A
Here is one way using dynamic query
DECLARE #prior_quarters INT = 4,
#int INT =1,
#col_list VARCHAR(max)=Quotename(CONVERT(VARCHAR(20), Getdate(), 101))
WHILE #int <= #prior_quarters
BEGIN
SELECT #col_list += Concat(',', Quotename(CONVERT(VARCHAR(20), Eomonth(Getdate(), ( ( ( ( Month(Getdate()) - 1 ) % 3 ) + 1 ) * -1 ) * #int), 101)))
SET #int+=1
END
--SELECT #col_list -- for debugging
EXEC ('select '+#col_list+' from yourtable')

Oracle SQL Adding IF statement

I have a pretty simple question me thinks. I've been looking on the internet, but haven't been able to find anything. I am trying to add an IF statement basically to my Oracle sql.
UPDATE PS_Z_TREND_NOW_TBL a
SET STATUS = (
SELECT COUNT(SEC.IS_AW_AUTH_NAME)
FROM PS_IS_AW_SECURITY sec
WHERE sec.IS_AW_AUTH_NAME LIKE '%Manager%'
I want to update STATUS so that if COUNT(SEC.IS_AW_AUTH_NAME) is greater than 0 it will insert 'M'. How would I write this?
With Case statements.
UPDATE PS_Z_TREND_NOW_TBL a
SET STATUS = ( CASE WHEN COUNT(SEC.IS_AW_AUTH_NAME) > 0 then 'M'
ELSE null END )
FROM PS_IS_AW_SECURITY sec
WHERE sec.IS_AW_AUTH_NAME LIKE '%Manager%'

Ckeck the presence of xml tag using oracle

<wbi:appData>
<wbi:content wbi:name="1st_status">
<wbi:value xsi:type="xsd:string">Success</wbi:value>
</wbi:content>
</wbi:appData>
this xml is in a table which has a column in the form of CLOB type.
I wanted to find if "wbi:value" tag exists in this xml or not ?
I tried using existsnode but in sql developer it is saying an error as to declare existsnode.
yes use existsnode:
SQL> with yourdata as (select to_clob('<wbi:event xmlns:wbi="http://foo" xmlns:xsi="http://x" xmlns:xsd="http://d">
2 <wbi:appData>
3 <wbi:content wbi:name="1st_status">
4 <wbi:value xsi:type="xsd:string">Success</wbi:value>
5 </wbi:content>
6 <wbi:content wbi:name="2nd_status">
7 <wbi:value xsi:type="xsd:string">Failure</wbi:value>
8 </wbi:content>
9 </wbi:appData>
10 </wbi:event>') c from dual)
11 select existsnode(xmltype(c), '/wbi:event/wbi:appData/wbi:content','xmlns:wbi="http://foo"') is_exist
12 from yourdata t
13 /
IS_EXIST
----------
1
ie
existsnode(xmltype(c), '/wbi:event/wbi:appData/wbi:content','xmlns:wbi="http://foo"')
1 = exists
0 = does not exist.
note that in my sample, i had two matching nodes (as i didn't filter on wbi:name). you can filter the xpath of course. eg:
/wbi:event/wbi:appData/wbi:content[#wbi:name="1st_status"]
to limit matches to the "1st_status" one
select count(*)
from clobtab
where existsNode(xmltype.createxml(clobcol),'/wbi:appData/wbi:content/wbi:value') = 1;
If it reurns more than 0 then it exists otherwise not.
So your trigger would be-
CREATE TRIGGER Tab_a
BEFORE INSERT
FOR EACH ROW
declare
xml_a xmltype;
begin
xml_a:=xmltype(:new.value);
if existsNode(xml_a,'/wbi:appData/wbi:content/wbi:value','xmlns:wbi="http://pat.namespace.com"') = 1
then
----insert ....
end if;
end;
actually you can use oracle's instr function, which is fast.
like:
where instr(field, 'wbi:value') > 0
You can use XMLEXISTS:
SELECT DESCRIPTOR_XML FROM TABLE_WITH_AN_XMLTYPE_COLUMN
WHERE
XMLEXISTS('//functions[function/arg[#name="class.name" and not(starts-with(., "com.example.apps.YouShantSeeMeClass"))]]'
PASSING BY VALUE DESCRIPTOR_XML);

How to search string to find data after end of pattern of characters (SQL DB2)

I need to find the next single event that appears after the last occurrence of the following pattern of events "5065|5373|5373". My problem is that the pattern can be in the string 1 to n times. Here's an example of the some data that I have to search through.
The events in BOLD are what i would be looking for.
5065|5373|5373|5065|5373|5373|5065|5373|5373|5509|5329|5321
5065|5373|5373|5065|5373|5373|5509|5270|5373|5373|5373|5080|5081|5013|5040|5295|5321
5065|5373|5373|5295|5323|5321
Any help would be greatly appreciated!
If you can't create a new stored procedure or UDF, here's a recursive query that'll do it for you:
WITH Recurs(id, index, token, source) as (
SELECT id, LOCATE('5065|5373|5373|', M.PATH_2), '', M.PATH_2
FROM M
UNION ALL
SELECT id, LOCATE('5065|5373|5373|', source, index + 15),
SUBSTR(source, index + 15, 4), source
FROM Recurs
WHERE index > 0)
SELECT *
FROM Recurs
WHERE index = 0
Which yields the expected:
ID INDEX TOKEN SOURCE
3 0 5295 5065|5373|5373|5295|5323|5321
2 0 5509 5065|5373|5373|5065|5373|5373|5509|5270|5373|5373|5373|5080|5081|5013|5040|5295|5321
1 0 5509 5065|5373|5373|5065|5373|5373|5065|5373|5373|5509|5329|5321
One fairly straightforward way to do this is with a recursive common table expression (CTE):
CREATE FUNCTION localutil.locatelastmatch(
searchparm VARCHAR(4000), inputparm VARCHAR(4000)
)
RETURNS SMALLINT
LANGUAGE SQL
RETURN
WITH rcurs(counter, output ) AS (
VALUES (0,0)
UNION ALL
SELECT counter+1, LOCATE(searchparm,inputparm,counter+1)
FROM rcurs
WHERE counter < LENGTH(inputparm) AND counter < 32767
)
SELECT MAX(output) FROM rcurs
;
It may not be the cheapest way to find the last matching occurrence, but it's at least a contender for it. By burying the complexity into a scalar user-defined function (UDF), you won't have to introduce the SQL recursion into every query that needs to search for the last instance of a pattern.
Here's how it works against your sample strings:
WITH originput(val) as (VALUES
('5065|5373|5373|5065|5373|5373|5065|5373|5373|5509|5329|5321'),
('5065|5373|5373|5065|5373|5373|5509|5270|5373|5373|5373|5080|5081|5013|5040|5295|5321'),
('5065|5373|5373|5295|5323|5321')
)
SELECT LENGTH(val) AS inputlength,
localutil.locatelastmatch( '5065|5373|5373|', val ) AS finaloffset,
SUBSTR(val, localutil.locatelastmatch( '5065|5373|5373|', val )
+ LENGTH( '5065|5373|5373|' ), 4) AS nextitem
FROM originput
;
INPUTLENGTH FINALOFFSET NEXTITEM
----------- ----------- --------
59 31 5509
84 16 5509
29 1 5295