I have an Oracle project that would be a good fit for using GUIDs as a key. I found the following snippet
SET SERVEROUTPUT ON
BEGIN
FOR indx IN 1 .. 5
LOOP
DBMS_OUTPUT.put_line ( SYS_GUID );
END LOOP;
END;
/
From http://feuerthoughts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html
When I run it against my database (I tried it on versions 10g and version 11) I get output like
64FE4083D6BA7CB4E0400F0A0E0A18B0
64FE4083D6BB7CB4E0400F0A0E0A18B0
64FE4083D6BC7CB4E0400F0A0E0A18B0
64FE4083D6BD7CB4E0400F0A0E0A18B0
64FE4083D6BE7CB4E0400F0A0E0A18B0
I.e. the value never changes! Is there something I have to do to set this up to work as expected?
Edit: I am not very observant - the GUIDs are changing, but it looks like I am suffering from the sequential GUID problem that the link above is talking about.
The value does change....
*
64FE4083D6BA7CB4E0400F0A0E0A18B0
64FE4083D6BB7CB4E0400F0A0E0A18B0
64FE4083D6BC7CB4E0400F0A0E0A18B0
64FE4083D6BD7CB4E0400F0A0E0A18B0
64FE4083D6BE7CB4E0400F0A0E0A18B0
*
Seems OK. From the description:
SYS_GUID generates and returns a
globally unique identifier (RAW value)
made up of 16 bytes. On most
platforms, the generated identifier
consists of a host identifier, a
process or thread identifier of the
process or thread invoking the
function, and a nonrepeating value
(sequence of bytes) for that process
or thread.
From your example:
64FE4083D6BA7CB4E0400F0A0E0A18B0
64FE4083D6BB7CB4E0400F0A0E0A18B0
64FE4083D6BC7CB4E0400F0A0E0A18B0
64FE4083D6BD7CB4E0400F0A0E0A18B0
64FE4083D6BE7CB4E0400F0A0E0A18B0
Nobody mentioned anything about the distribution of these GUID values. They should be nonrepeating and they are. Unless you get exactly the same output every time.
Related
Reading the following documentation:
https://learn.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagkbdllhookstruct
The bit 4 (counting from 0), is defined as - "Specifies whether the event was injected. The value is 1 if that is the case; otherwise, it is 0. Note that bit 1 is not necessarily set when bit 4 is set."
What is the actual definition of "injected event?" in this context?
You'd think it was an easier thing to google.
If you look at Microsoft's documentation for the SendInput function it describes what it does as inserting or injecting input:
"The function returns the number of events that it successfully inserted into the keyboard or mouse input stream. .... This function is subject to UIPI. Applications are permitted to inject input only into applications that are at an equal or lesser integrity level."
Keyboard input generated by the user and sent from the device driver will not have the bit set. Input created using API functions will have the bit set.
I have a problem here while exporting data from oracle database to CSV file using a procedure. While exporting data, sometimes the CSV file is getting truncated and the error it shows is "ORA-29285 - File write error". The problem here is the file is getting truncated not all the times but randomly.
Edit : Below is the chunk of code I used in my procedure
conn := utl_file.fopen('sample_directory','output.csv','W',4096);
for i in (select * from per_data)
loop
utl_file.put_line(conn,i.name||','||i.sub||','||to_char(i.start_date,'dd-mon-yy')||','||to_char(i.expire_date,'dd-mon-yy')||','||i.loc||CHR(13));
end loop;
utl_file.fclose(conn);`
I am pulling my hair to trace out the reason. Can someone help me out ?
One way to get this error is to open the file with a certain maximum line size - possibly the default 1024 - and then try to write a single line to that file which is longer than that.
In your case you don't seem to be doing that, as you open it with 4096 and your lines are all (apparently) shorter than that.
So you may be hitting the 32k limitation:
The maximum size of the buffer parameter is 32767 bytes unless you specify a smaller size in FOPEN. If unspecified, Oracle supplies a default value of 1024. The sum of all sequential PUT calls cannot exceed 32767 without intermediate buffer flushes.
You don't seem to be doing any flushing. You could change your put_line call to auto-flush:
utl_file.put_line(conn,
i.name||','||i.sub||','||to_char(i.start_date,'dd-mon-yy')
||','||to_char(i.expire_date,'dd-mon-yy')||','||i.loc||CHR(13),
true);
or keep a counter in your loop and manually flush every 100 lines (or whatever number works and is efficient for you).
As noted in the documentation:
If there is buffered data yet to be written when FCLOSE runs, you may receive WRITE_ERROR when closing a file.
You aren't flushing before you close, so adding an explicit flush - even if you have autoflush set to true - might also help avoid this, at least if the exception is being thrown by the fclose() call rather than by put_line():
...
end loop;
utl_file.fflush(conn);
utl_file.fclose(conn);
I have a Delphi application that reads data form a file and stores it in an array. Each row in a file contains an address, lineTypeIndicator and data. This is the algorithm (contains code that I believe is critical):
AssignFile(inputFile, inFileName);
Reset(inputFile);
while not EOF(inputFile) do
begin
Readln(inputFile,fileLineBuffer);
if Copy(fileLineBuffer, 8, 2) = '01' then //Never managed to catch the error here
begin
break;
end;
//extract the address from the line and use it to determine max and min address.
end;
//Now that you have min and max address, use it to set the length of an char array
SetLength(memoryArray,(lastAddress - firstAddress) * 2);
Reset(inputFile);
while not EOF(inputFile) do
begin
Readln(inputFile,fileLineBuffer);
if Copy(fileLineBuffer, 8, 2) = '01' then //I caught all the errors here
begin
break;
end;
//extract the address and data from the fileLineBuffer and place it in the corresponding place in an array
end;
This code is executed every time the user clicks the corresponding button on a form. It runs the first few times it is executed, but then after a few runs i get this:
MyProgram.exe faulted with message: 'access violation at 0x00406111:
write of address 0x00090d1c (this varies). Proceess stopped. Use step
or run to continue.
To me, this smells like some kind of heap overflow. I have tried replacing
if Copy(fileLineBuffer, 8, 2) = '01' then
with
lineTypeBuffer := Copy(fileLineBuffer, 8, 2);
if lineTypeBuffer = '01' then
or
if (fileLineBuffer[8] = '0') and (fileLineBuffer[9] = '1') then
but it did not help.
Any suggestions on how I should approach this problem?
P.S. Tried running it on Win7 32 bit and Win7 64 bit - no difference
P.P.S. sorry for the long question.
The only explanation for
Copy(fileLineBuffer, 8, 2) = '01'
resulting in an access violation is that you have corrupted the heap.
Something else in your program is writing out of bounds and corrupting the heap. Such problems can be tricky to diagnose because the fault is typically in one part of the code, but the error occurs elsewhere. Some code corrupts the heap, and then a subsequent heap operation fails because of the earlier heap corruption.
I am confident in my diagnosis because Delphi string variables are known to work, Copy is known to work, and string equality testing is known to work. In other words there is no fault in the line of code at which the error occurs. Ergo the error is elsewhere.
Some debugging tools that might help:
FastMM in full debug mode.
Range checking (enabled from the project's compiler options).
I am trying to get to know the pgAdmin debugger and am fairly new to PostgreSQL. I don't know if the behavior I'm seeing is because of a mistake I am making or simply because of limitations in the debugger.
At the top of my function I've declared two variables:
declare tuple record;
declare buffer text;
In the body of my function I am trying to iterate the rows in temporary table TT_CALENDAR, so it would be possible to examine the contents of the temporary table in the Locals window:
for tuple in
select startdate, enddate from TT_CALENDAR
loop
buffer := concat(buffer, tuple.startdate::text, tuple.enddate::text,'|');
end loop;
buffer :='';
Breakpoints are set at buffer := concat(... and at the line buffer :=''; and program execution stops there as expected, but as soon as we exit the loop and arrive at buffer :=''; the string value vanishes from the Locals window.
Why would buffer's displayed value vanish from the Locals window when we exit the loop before buffer :=''; is executed? It's as if the variable has gone out of scope.
P.S. Is there a configuration setting that would cause long values to wrap in the Locals window Value cell?
Thank you
This really sounds like a bug with the debugger. I would generally recommend following up on the pgadmin email lists and alert the developers to this problem.
There is no reason I know that the variables would be out of scope so it sounds to me like it is a bug in the debugger itself.
What is the difference of performance between standalone procedure and packaged procedure? Which will be good performance wise and why? Is there any difference in execution of both?
Tom says:
Always use a package.
Never use a standalone procedure
except for demos, tests and standalone
utilities (that call nothing and are
called by nothing)
There you can also find a very good discussion about their performance. Just search for "performance" on that page.
If still seriously in doubt, you can always test yourself which one is faster. You'll certainly learn something new by doing so.
My take on your question: while it's true that calling package procedures/functions seems to be slower in certain situations than calling standalone procedures/functions, the advantages offered by the additional features available when using packages far outweigh the performance loss. So, just like Tom puts it, use packages.
The link: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:7452431376537
Test code(20 million calls, runstats_pkg is a package I wrote based on the runstats package by Tom Kyte):
CREATE OR REPLACE PACKAGE testperf AS
FUNCTION pow(i INT) RETURN INT;
END;
/
CREATE OR REPLACE PACKAGE BODY testperf AS
FUNCTION pow(i int) RETURN INT AS
BEGIN
RETURN i * i;
END;
END;
/
CREATE OR REPLACE FUNCTION powperf(i INT) RETURN INT AS
BEGIN
RETURN i * i;
END;
/
DECLARE
I INT;
S INT DEFAULT 0;
BEGIN
runstats_pkg.start1;
FOR I IN 1 .. 20000000 LOOP
s := s + (powperf(i) / i);
END LOOP;
runstats_pkg.stop1;
dbms_output.put_line(s);
s := 0;
runstats_pkg.start2;
FOR I IN 1 .. 20000000 LOOP
s := s + (testperf.pow(i) / i);
END LOOP;
runstats_pkg.stop2;
dbms_output.put_line(s);
runstats_pkg.show;
END;
Results(Oracle XE):
Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
2,491 2,439 -52 102.13%
Run1 ran in 2304 hsecs
Run2 ran in 2364 hsecs
run 1 ran in 97.46% of the time
Results(Oracle 11g R1, different machine):
Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
2,990 3,056 66 97.84%
Run1 ran in 2071 hsecs
Run2 ran in 2069 hsecs
run 1 ran in 100.1% of the time
So, there you go. Really not much of a difference.
Want data for something more complex that also involves SQL DML? You gotta test it yourself.
There isn't a performance difference except that packages can have state and standalone procedures and functions not.
The use of package is more about ordening and grouping of code. You could see them as an alternative of namespaces.
The primary reason to use packages is they break the dependency chain. For instance if you have two stand-alone procedures, procedure A which calls procedure B and you recompile procedure B you will also need to recompile procedure A. This gets quite complicated as you increase the number of procedures and functions.
If you move these to two to different packages you will not need to recompile them as long as the specification does not change.
There should be no difference between the two.
A major use of packages is to group a set of similar/associeted functions+procedures
The other answers here are all good (e.g. packages have state, they separate interface from implementation, etc).
Another difference is when procedures or packages are wrapped - it is simple to unwrap a procedure, but not a package body.