on 11-14-2007 2:07 PM
Hi,
in a production application i must, change decodes to user defined functions, and using functions the where clause dont works, to better understand i created a test case.
the DDL is:
CREATE TABLE account (
id VARCHAR(8) NOT NULL,
account_number VARCHAR(9),
name VARCHAR(30),
subaccount_Type VARCHAR(2),
PRIMARY KEY (id)
)
//
CREATE TABLE customer (
id VARCHAR(8) NOT NULL,
name VARCHAR(30),
account_order VARCHAR(2),
PRIMARY KEY (id)
)
//
CREATE TABLE product (
id VARCHAR(8),
name VARCHAR(30),
account_order VARCHAR(2),
PRIMARY KEY (id)
)
//
CREATE TABLE balance (
account_id VARCHAR(8),
subaccount_id VARCHAR(8)
)
//
populate with some data
INSERT INTO account VALUES ('00000001','1','INVENTORY','PD')
//
INSERT INTO account VALUES ('00000002','2','TO RECEIVE','CS')
//
INSERT INTO customer VALUES ('00000003','CUSTOMER 1','01')
//
INSERT INTO customer VALUES ('00000004','CUSTOMER 2','02')
//
INSERT INTO product VALUES ('00000005','PRODUCT 1','01')
//
INSERT INTO product VALUES ('00000006','PRODUCT 2','02')
//
INSERT INTO balance VALUES ('00000001','00000001')
//
INSERT INTO balance VALUES ('00000001','00000005')
//
INSERT INTO balance VALUES ('00000001','00000006')
//
INSERT INTO balance VALUES ('00000002','00000002')
//
INSERT INTO balance VALUES ('00000002','00000003')
//
INSERT INTO balance VALUES ('00000002','00000004')
//
the old SQL with DECODES:
SELECT
a.account_number ||
DECODE(INDEX(b.account_id,b.subaccount_id),1,'',
DECODE(a.subaccount_Type,'CS',c.account_order,'PD',p.account_order)
) account_number,
DECODE(INDEX(b.account_id,b.subaccount_id),1,a.name,
DECODE(a.subaccount_Type,'CS',c.name,'PD',p.name)
) account_name
FROM balance b, customer c, product p, account a
WHERE
a.id = account_id AND
c.id(+) = b.subaccount_id AND
p.id(+) = b.subaccount_id AND
b.account_id = '00000001'
functions to avoid DECODES:
CREATE FUNCTION APP_NAME.getAccountNumber (
ACCOUNT_ID CHAR(8),
SUBACCOUNT_ID CHAR(8)
) RETURNS CHAR(20) AS
VAR accountNumber CHAR(20);
subaccountType CHAR(2);
name CHAR(30);
accountOrder CHAR(2);
BEGIN
TRY
SELECT account_number, subaccount_Type, name FROM APP_NAME.Account WHERE id = :ACCOUNT_ID;
WHILE $rc = 0 DO BEGIN
FETCH INTO :accountNumber, :subaccountType, :name;
END;
CATCH
IF $rc <> 100 THEN STOP ($rc, 'unexpected error');
IF (SUBACCOUNT_ID != ACCOUNT_ID) THEN BEGIN
IF subaccountType = 'CS' THEN BEGIN
TRY
SELECT account_order, name FROM APP_NAME.Customer WHERE id = :SUBACCOUNT_ID;
WHILE $rc = 0 DO BEGIN
FETCH INTO :accountOrder, :name;
SET accountNumber = accountNumber || accountOrder;
END;
CATCH
IF $rc <> 100 THEN STOP ($rc, 'unexpected error');
END;
IF subaccountType = 'PD' THEN BEGIN
TRY
SELECT account_order, name FROM APP_NAME.Product WHERE id = :SUBACCOUNT_ID;
WHILE $rc = 0 DO BEGIN
FETCH INTO :accountOrder, :name;
SET accountNumber = accountNumber || accountOrder;
END;
CATCH
IF $rc <> 100 THEN STOP ($rc, 'unexpected error');
END;
END;
RETURN accountNumber;
END;
//
CREATE FUNCTION APP_NAME.getAccountName (
ACCOUNT_ID CHAR(8),
SUBACCOUNT_ID CHAR(8)
) RETURNS CHAR(30) AS
VAR accountNumber CHAR(20);
subaccountType CHAR(2);
name CHAR(30);
accountOrder CHAR(2);
BEGIN
TRY
SELECT account_number, subaccount_Type, name FROM APP_NAME.Account WHERE id = :ACCOUNT_ID;
WHILE $rc = 0 DO BEGIN
FETCH INTO :accountNumber, :subaccountType, :name;
END;
CATCH
IF $rc <> 100 THEN STOP ($rc, 'unexpected error');
IF (SUBACCOUNT_ID != ACCOUNT_ID) THEN BEGIN
IF subaccountType = 'CS' THEN BEGIN
TRY
SELECT account_order, name FROM APP_NAME.Customer WHERE id = :SUBACCOUNT_ID;
WHILE $rc = 0 DO BEGIN
FETCH INTO :accountOrder, :name;
SET accountNumber = accountNumber || accountOrder;
END;
CATCH
IF $rc <> 100 THEN STOP ($rc, 'unexpected error');
END;
IF subaccountType = 'PD' THEN BEGIN
TRY
SELECT account_order, name FROM APP_NAME.Product WHERE id = :SUBACCOUNT_ID;
WHILE $rc = 0 DO BEGIN
FETCH INTO :accountOrder, :name;
SET accountNumber = accountNumber || accountOrder;
END;
CATCH
IF $rc <> 100 THEN STOP ($rc, 'unexpected error');
END;
END;
RETURN name;
END;
//
new SQL using User Defined FUNCTIONS:
SELECT
APP_NAME.getAccountNumber(b.account_id,b.subaccount_id) account_number,
APP_NAME.getAccountName(b.account_id,b.subaccount_id) account_name
FROM balance b
WHERE
b.account_id = '00000001'
but this SQL dont returns any row, but removing the WHERE clause returns.
using something like:
SELECT
APP_NAME.getAccountNumber(b.account_id,b.subaccount_id) account_number,
APP_NAME.getAccountName(b.account_id,b.subaccount_id) account_name
FROM balance b
this sql returns all rows, and works like the version with DECODE but without using the WHERE clause.
is this a BUG or a limitation of user defined function?
i'm using MaxDB version 'X64/LIX86 7.6.03 Build 007-123-157-515'
thanks for any help
Clóvis
Hi Clovis,
I did also check with 7.6.03 Build 9. This also works, but only with a simpler function:
create function foo (test varchar) returns varchar as
return test;
SELECT
foo(b.account_id&b.subaccount_id) account_number,
foo(b.account_id&b.subaccount_id) account_name
FROM balance b
WHERE
b.account_id = '00000001'
ACCOUNT_NUMBER ACCOUNT_NAME
0000000100000001 0000000100000001
0000000100000005 0000000100000005
0000000100000006 0000000100000006
So it's not a problem with user defined functions in general...
KR Lars
BTW:
this is one of the best prepared problem descriptions I ever saw on this forum.
DDL, DML, expected result and actual result.
That's really something one can work with!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi, Lars,
I checked here too with your simpler function, and works, appears to be a problem when a function execute a SELECT statement, with that in mind i changed your function to execute a SELECT statement inside, and with that the result of the same caller statement is no result:
simpler function with SELECT statement:
create function foo(test char(16)) returns char(16) as
var dualTest char(16);
begin
TRY
SELECT '01' FROM DBA.DUAL;
WHILE $rc = 0 DO BEGIN
FETCH INTO :dualTest;
END;
CATCH
IF $rc <> 100 THEN STOP ($rc, 'unexpected error');
return test;
end;
ps: i changed varchar to char(16) because on my version i get the message (-9000 POS(84) System error: Not yet implemented:parameter of unknown size)
well i have a BUG on my version, since i'm not a SAP customer, what is the chance to i get a patch for that? or have a estimative when a newer version will be deployed on SDN?
best regards
Clóvis
Hi Clovis,
do you have a support contract for your MaxDB? E.g. from mySQL?
In that case you can ask them for a patch.
Otherwise you basically just have to wait until a new version is released on the SDN.
Due to the license agreement for the community edition, the software comes 'as-is- with all faults...
http://maxdb.sap.com/license/MaxDB_Community_License_2007.pdf
Concerning the issue itself...
this also works on my 7.6.03 Build 9.
Perhabs it's something with your parameter setup... can you post your current parameters?
KR Lars
Hi Lars,
i dont have a contract support for my MaxDB, SAP will provide this? or i must get this only from mySQL?
follow is the post of database parameters extracted with param_directgetall command:
KERNELVERSION KERNEL 7.6.03 BUILD 007-123-157-515
INSTANCE_TYPE OLTP
MCOD NO
_SERVERDB_FOR_SAP YES
_UNICODE NO
DEFAULT_CODE ASCII
DATE_TIME_FORMAT ISO
CONTROLUSERID DBM
CONTROLPASSWORD
MAXLOGVOLUMES 2
MAXDATAVOLUMES 11
LOG_VOLUME_NAME_001 /db/SPDT/log/log01.dat
LOG_VOLUME_TYPE_001 F
LOG_VOLUME_SIZE_001 6400
DATA_VOLUME_NAME_0005 /db/SPDT/data/data05.dat
DATA_VOLUME_NAME_0004 /db/SPDT/data/data04.dat
DATA_VOLUME_NAME_0003 /db/SPDT/data/data03.dat
DATA_VOLUME_NAME_0002 /db/SPDT/data/data02.dat
DATA_VOLUME_NAME_0001 /db/SPDT/data/data01.dat
DATA_VOLUME_TYPE_0005 F
DATA_VOLUME_TYPE_0004 F
DATA_VOLUME_TYPE_0003 F
DATA_VOLUME_TYPE_0002 F
DATA_VOLUME_TYPE_0001 F
DATA_VOLUME_SIZE_0005 524288
DATA_VOLUME_SIZE_0004 524288
DATA_VOLUME_SIZE_0003 524288
DATA_VOLUME_SIZE_0002 524288
DATA_VOLUME_SIZE_0001 524288
DATA_VOLUME_MODE_0005 NORMAL
DATA_VOLUME_MODE_0004 NORMAL
DATA_VOLUME_MODE_0003 NORMAL
DATA_VOLUME_MODE_0002 NORMAL
DATA_VOLUME_MODE_0001 NORMAL
DATA_VOLUME_GROUPS 1
LOG_BACKUP_TO_PIPE NO
MAXBACKUPDEVS 2
LOG_MIRRORED NO
MAXVOLUMES 14
LOG_IO_BLOCK_COUNT 8
DATA_IO_BLOCK_COUNT 64
BACKUP_BLOCK_CNT 64
_DELAY_LOGWRITER 0
LOG_IO_QUEUE 50
_RESTART_TIME 600
MAXCPU 1
MAX_LOG_QUEUE_COUNT 0
USED_MAX_LOG_QUEUE_COUNT 1
LOG_QUEUE_COUNT 1
MAXUSERTASKS 50
_TRANS_RGNS 8
_TAB_RGNS 8
_OMS_REGIONS 0
_OMS_RGNS 7
OMS_HEAP_LIMIT 0
OMS_HEAP_COUNT 1
OMS_HEAP_BLOCKSIZE 10000
OMS_HEAP_THRESHOLD 100
OMS_VERS_THRESHOLD 2097152
HEAP_CHECK_LEVEL 0
_ROW_RGNS 8
RESERVEDSERVERTASKS 16
MINSERVERTASKS 28
MAXSERVERTASKS 28
_MAXGARBAGE_COLL 1
_MAXTRANS 408
MAXLOCKS 12080
_LOCK_SUPPLY_BLOCK 100
DEADLOCK_DETECTION 4
SESSION_TIMEOUT 900
OMS_STREAM_TIMEOUT 30
REQUEST_TIMEOUT 5000
_IOPROCS_PER_DEV 2
_IOPROCS_FOR_PRIO 0
_IOPROCS_FOR_READER 0
_USE_IOPROCS_ONLY NO
_IOPROCS_SWITCH 2
LRU_FOR_SCAN NO
_PAGE_SIZE 8192
_PACKET_SIZE 131072
_MINREPLY_SIZE 4096
_MBLOCK_DATA_SIZE 32768
_MBLOCK_QUAL_SIZE 32768
_MBLOCK_STACK_SIZE 32768
_MBLOCK_STRAT_SIZE 16384
_WORKSTACK_SIZE 8192
_WORKDATA_SIZE 8192
_CAT_CACHE_MINSIZE 262144
CAT_CACHE_SUPPLY 9664
INIT_ALLOCATORSIZE 262144
ALLOW_MULTIPLE_SERVERTASK_UKTS NO
_TASKCLUSTER_01 tw;al;ut;2000*sv,100*bup;10*ev,10*gc;
_TASKCLUSTER_02 ti,100*dw;30000*us;
_TASKCLUSTER_03 compress
_DYN_TASK_STACK NO
_MP_RGN_QUEUE YES
_MP_RGN_DIRTY_READ DEFAULT
_MP_RGN_BUSY_WAIT DEFAULT
_MP_DISP_LOOPS 2
_MP_DISP_PRIO DEFAULT
MP_RGN_LOOP -1
_MP_RGN_PRIO DEFAULT
MAXRGN_REQUEST -1
_PRIO_BASE_U2U 100
_PRIO_BASE_IOC 80
_PRIO_BASE_RAV 80
_PRIO_BASE_REX 40
_PRIO_BASE_COM 10
_PRIO_FACTOR 80
_DELAY_COMMIT NO
_MAXTASK_STACK 512
MAX_SERVERTASK_STACK 500
MAX_SPECIALTASK_STACK 500
_DW_IO_AREA_SIZE 50
_DW_IO_AREA_FLUSH 50
FBM_VOLUME_COMPRESSION 50
FBM_VOLUME_BALANCE 10
_FBM_LOW_IO_RATE 10
CACHE_SIZE 32768
_DW_LRU_TAIL_FLUSH 25
XP_DATA_CACHE_RGNS 0
_DATA_CACHE_RGNS 16
XP_CONVERTER_REGIONS 0
CONVERTER_REGIONS 8
XP_MAXPAGER 0
MAXPAGER 16
SEQUENCE_CACHE 1
_IDXFILE_LIST_SIZE 2048
VOLUMENO_BIT_COUNT 8
OPTIM_MAX_MERGE 500
OPTIM_INV_ONLY YES
OPTIM_CACHE NO
OPTIM_JOIN_FETCH 0
JOIN_SEARCH_LEVEL 0
JOIN_MAXTAB_LEVEL4 16
JOIN_MAXTAB_LEVEL9 5
_READAHEAD_BLOBS 32
CLUSTER_WRITE_THRESHOLD 80
CLUSTERED_LOBS NO
RUNDIRECTORY /var/opt/sdb/data/wrk/SPDT
OPMSG1 /dev/console
OPMSG2 /dev/null
_KERNELDIAGFILE knldiag
KERNELDIAGSIZE 800
_EVENTFILE knldiag.evt
_EVENTSIZE 0
_MAXEVENTTASKS 2
_MAXEVENTS 100
_KERNELTRACEFILE knltrace
TRACE_PAGES_TI 2
TRACE_PAGES_GC 20
TRACE_PAGES_LW 5
TRACE_PAGES_PG 3
TRACE_PAGES_US 10
TRACE_PAGES_UT 5
TRACE_PAGES_SV 5
TRACE_PAGES_EV 2
TRACE_PAGES_BUP 0
KERNELTRACESIZE 725
EXTERNAL_DUMP_REQUEST NO
_AK_DUMP_ALLOWED YES
_KERNELDUMPFILE knldump
_RTEDUMPFILE rtedump
_UTILITY_PROTFILE dbm.utl
UTILITY_PROTSIZE 100
_BACKUP_HISTFILE dbm.knl
_BACKUP_MED_DEF dbm.mdf
_MAX_MESSAGE_FILES 0
_SHMKERNEL 6356
__PARAM_CHANGED___ 0
__PARAM_VERIFIED__ 2007-09-10 15:58:04
DIAG_HISTORY_NUM 2
DIAG_HISTORY_PATH /var/opt/sdb/data/wrk/SPDT/DIAGHISTORY
_DIAG_SEM 1
SHOW_MAX_STACK_USE NO
SHOW_MAX_KB_STACK_USE NO
LOG_SEGMENT_SIZE 2133
_COMMENT
SUPPRESS_CORE YES
FORMATTING_MODE PARALLEL
FORMAT_DATAVOLUME YES
OFFICIAL_NODE
UKT_CPU_RELATIONSHIP NONE
HIRES_TIMER_TYPE CPU
LOAD_BALANCING_CHK 0
LOAD_BALANCING_DIF 10
LOAD_BALANCING_EQ 5
HS_STORAGE_DLL libhsscopy
HS_SYNC_INTERVAL 50
USE_OPEN_DIRECT YES
USE_OPEN_DIRECT_FOR_BACKUP NO
SYMBOL_DEMANGLING NO
EXPAND_COM_TRACE NO
JOIN_TABLEBUFFER 128
SET_VOLUME_LOCK YES
SHAREDSQL YES
SHAREDSQL_CLEANUPTHRESHOLD 25
SHAREDSQL_COMMANDCACHESIZE 262144
MEMORY_ALLOCATION_LIMIT 0
USE_SYSTEM_PAGE_CACHE YES
USE_COROUTINES YES
FORBID_LOAD_BALANCING YES
MIN_RETENTION_TIME 60
MAX_RETENTION_TIME 480
MAX_SINGLE_HASHTABLE_SIZE 512
MAX_HASHTABLE_MEMORY 5120
ENABLE_CHECK_INSTANCE YES
RTE_TEST_REGIONS 0
HASHED_RESULTSET YES
HASHED_RESULTSET_CACHESIZE 262144
CHECK_HASHED_RESULTSET 0
AUTO_RECREATE_BAD_INDEXES NO
AUTHENTICATION_ALLOW
AUTHENTICATION_DENY
TRACE_AK NO
TRACE_DEFAULT NO
TRACE_DELETE NO
TRACE_INDEX NO
TRACE_INSERT NO
TRACE_LOCK NO
TRACE_LONG NO
TRACE_OBJECT NO
TRACE_OBJECT_ADD NO
TRACE_OBJECT_ALTER NO
TRACE_OBJECT_FREE NO
TRACE_OBJECT_GET NO
TRACE_OPTIMIZE NO
TRACE_ORDER NO
TRACE_ORDER_STANDARD NO
TRACE_PAGES NO
TRACE_PRIMARY_TREE NO
TRACE_SELECT NO
TRACE_TIME NO
TRACE_UPDATE NO
TRACE_STOP_ERRORCODE 0
TRACE_ALLOCATOR 0
TRACE_CATALOG 0
TRACE_CLIENTKERNELCOM 0
TRACE_COMMON 0
TRACE_COMMUNICATION 0
TRACE_CONVERTER 0
TRACE_DATACHAIN 0
TRACE_DATACACHE 0
TRACE_DATAPAM 0
TRACE_DATATREE 0
TRACE_DATAINDEX 0
TRACE_DBPROC 0
TRACE_FBM 0
TRACE_FILEDIR 0
TRACE_FRAMECTRL 0
TRACE_IOMAN 0
TRACE_IPC 0
TRACE_JOIN 0
TRACE_KSQL 0
TRACE_LOGACTION 0
TRACE_LOGHISTORY 0
TRACE_LOGPAGE 0
TRACE_LOGTRANS 0
TRACE_LOGVOLUME 0
TRACE_MEMORY 0
TRACE_MESSAGES 0
TRACE_OBJECTCONTAINER 0
TRACE_OMS_CONTAINERDIR 0
TRACE_OMS_CONTEXT 0
TRACE_OMS_ERROR 0
TRACE_OMS_FLUSHCACHE 0
TRACE_OMS_INTERFACE 0
TRACE_OMS_KEY 0
TRACE_OMS_KEYRANGE 0
TRACE_OMS_LOCK 0
TRACE_OMS_MEMORY 0
TRACE_OMS_NEWOBJ 0
TRACE_OMS_SESSION 0
TRACE_OMS_STREAM 0
TRACE_OMS_VAROBJECT 0
TRACE_OMS_VERSION 0
TRACE_PAGER 0
TRACE_RUNTIME 0
TRACE_SHAREDSQL 0
TRACE_SQLMANAGER 0
TRACE_SRVTASKS 0
TRACE_SYNCHRONISATION 0
TRACE_SYSVIEW 0
TRACE_TABLE 0
TRACE_VOLUME 0
CHECK_BACKUP NO
CHECK_DATACACHE NO
CHECK_KB_REGIONS NO
CHECK_LOCK NO
CHECK_LOCK_SUPPLY NO
CHECK_REGIONS NO
CHECK_TASK_SPECIFIC_CATALOGCACHE NO
CHECK_TRANSLIST NO
CHECK_TREE NO
CHECK_TREE_LOCKS NO
CHECK_COMMON 0
CHECK_CONVERTER 0
CHECK_DATAPAGELOG 0
CHECK_DATAINDEX 0
CHECK_FBM 0
CHECK_IOMAN 0
CHECK_LOGHISTORY 0
CHECK_LOGPAGE 0
CHECK_LOGTRANS 0
CHECK_LOGVOLUME 0
CHECK_SRVTASKS 0
OPTIMIZE_AGGREGATION YES
OPTIMIZE_FETCH_REVERSE YES
OPTIMIZE_STAR_JOIN YES
OPTIMIZE_JOIN_ONEPHASE YES
OPTIMIZE_JOIN_OUTER YES
OPTIMIZE_MIN_MAX YES
OPTIMIZE_FIRST_ROWS YES
OPTIMIZE_OPERATOR_JOIN YES
OPTIMIZE_JOIN_HASHTABLE YES
OPTIMIZE_JOIN_HASH_MINIMAL_RATIO 1
OPTIMIZE_OPERATOR_JOIN_COSTFUNC YES
OPTIMIZE_JOIN_PARALLEL_MINSIZE 1000000
OPTIMIZE_JOIN_PARALLEL_SERVERS 0
OPTIMIZE_JOIN_OPERATOR_SORT YES
OPTIMIZE_QUAL_ON_INDEX YES
DDLTRIGGER YES
SUBTREE_LOCKS NO
MONITOR_READ 2147483647
MONITOR_TIME 2147483647
MONITOR_SELECTIVITY 0
MONITOR_ROWNO 0
CALLSTACKLEVEL 0
OMS_RUN_IN_UDE_SERVER NO
OPTIMIZE_QUERYREWRITE OPERATOR
TRACE_QUERYREWRITE 0
CHECK_QUERYREWRITE 0
PROTECT_DATACACHE_MEMORY NO
LOCAL_REDO_LOG_BUFFER_SIZE 0
FILEDIR_SPINLOCKPOOL_SIZE 10
TRANS_HISTORY_SIZE 0
TRANS_THRESHOLD_VALUE 60
ENABLE_SYSTEM_TRIGGERS YES
DBFILLINGABOVELIMIT 70L80M85M90H95H96H97H98H99H
DBFILLINGBELOWLIMIT 70L80L85L90L95L
LOGABOVELIMIT 50L75L90M95M96H97H98H99H
AUTOSAVE 1
BACKUPRESULT 1
CHECKDATA 1
EVENT 1
ADMIN 1
ONLINE 1
UPDSTATWANTED 1
OUTOFSESSIONS 3
ERROR 3
SYSTEMERROR 3
DATABASEFULL 1
LOGFULL 1
LOGSEGMENTFULL 1
STANDBY 1
USESELECTFETCH YES
USEVARIABLEINPUT NO
UPDATESTAT_PARALLEL_SERVERS 0
UPDATESTAT_SAMPLE_ALGO 1
SIMULATE_VECTORIO IF_OPEN_DIRECT_OR_RAW_DEVICE
COLUMNCOMPRESSION YES
TIME_MEASUREMENT NO
CHECK_TABLE_WIDTH NO
MAX_MESSAGE_LIST_LENGTH 100
SYMBOL_RESOLUTION YES
PREALLOCATE_IOWORKER NO
CACHE_IN_SHARED_MEMORY NO
INDEX_LEAF_CACHING 2
NO_SYNC_TO_DISK_WANTED NO
SPINLOCK_LOOP_COUNT 30000
SPINLOCK_BACKOFF_BASE 1
SPINLOCK_BACKOFF_FACTOR 2
SPINLOCK_BACKOFF_MAXIMUM 64
ROW_LOCKS_PER_TRANSACTION 50
USEUNICODECOLUMNCOMPRESSION NO
best regards
Clóvis
Hi Clovis,
hmmm...browsing through the parameters I don't find anything suspicious...
So currently all I can tell you is to wait for the next release of the community edition. Sorry about that.
Concerning the support offering: I <b>assume</b> that SAP will come up with a offering for support services for non-SAP customers in the next months.
About the MySQL I don't know what they still offer.
Best regards,
Lars
Hi Clovis,
I retried your example with MaxDB 7.6.04 Build 11 and was able to reproduce the behaviour.
By checking the execution plan for the statement with your user functions I figured out, that the BALANCE table does not have a primary key.
I added a primary over ACCOUNT_ID,SUBACCOUNT_ID and afterwards the statement worked fine.
The same happened when I did not add a primary key but just a index on account_id.
Currently I can only assume, that there is a kind of glitch in the optimizer that leads to this issue, when a TABLE SCAN is chosen without using a restriction on a key or an index.
Does this workaround (creating an index or primary key) work for you as well?
KR Lars
Hi Lars,
i tried on versions 7.6.03.07 and 7.6.03.15 and with PK works, but with index dont works, i think that is because the optimizer choose TABLE SCAN, i think that optimizer dont uses the INDEX because the table have low data, right?
now i will try to use the function on the production system (7.6.03.07), but i'm worried if this works in all cases, can we have this "glitch in the optimizer" solved?
KR
Clóvis
Hi Clovis,
you're right - as soon as it looks cheaper to use the table scan this will be done.
To be on the save side you can try to add the
/+KEYACCESS/
hint to the select.
That way the query will always be processed via the KEY.
I will try to find out more about this error and forward it to the development.
KR Lars
Hi Lars,
with the hint KEYACCESS, works too, there is a way for us at OpenSource side to know the documentation about the hints? i checked the optimizer training material, and that says that explanation is at SAP note 832544 but from here i cant access SAP notes, exists another doc that explain hints?
KR
Clóvis
Hi Clovis,
of course these information are available to Open Source.
In fact there is much more internal information available to the community than what is only accessible to SAP customers.
[Check the MaxDB Wiki!|https://wiki.sdn.sap.com/wiki/x/gjc]
That should be the first place to look for anything about MaxDB - ok just after the documentation...
There is a chapter ["Tuning MaxDB - SQL Optimizer - Hints for the Optimizing Tool"|https://wiki.sdn.sap.com/wiki/x/Oig].
There you'll find the description of all optimizer hints.
Anyhow - the hints should usually only be used for analysis purposes and not (as in Oracle) be put into productive environments.
KR Lars
Hi Clovis,
sorry for the delay, but I have been on holiday last week.
But today I found time to analyze the problem. I think this is a bug, which has to do with user defined functions indirectly only.
I assume you used SQL Studio to verify the results. SQL Studio internally uses FETCH LAST, which may return no result in some rare cases (for example if user defined functions are involved and if the last row found by the strategy does not fulfill the qualification).
We will fix this bug as soon as possible.
Best Regards,
Thomas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
I remember some trouble with functions including selects, used in selects, in case no resulttablenames were specified.
Did you check if
declare <some_name> cursor for
select ...
and then
fetch <the same name> into ...
in your functions and having different names for every single select in (at least
with every function having different names for all selects in that one function) ?
There were users who succeeded with similar version of MaxDB after such a change.
Elke
Example:
CREATE FUNCTION KERN.GETACCOUNTNUMBER (
ACCOUNT_ID CHAR(8),
SUBACCOUNT_ID CHAR(8)
) RETURNS CHAR(20) AS
VAR ACCOUNTNUMBER CHAR(20);
SUBACCOUNTTYPE CHAR(2);
NAME CHAR(30);
ACCOUNTORDER CHAR(2);
BEGIN
TRY
DECLARE ANO_1 CURSOR FOR
SELECT ACCOUNT_NUMBER, SUBACCOUNT_TYPE, NAME
FROM KERN.ACCOUNT WHERE ID = :ACCOUNT_ID;
WHILE $RC = 0 DO BEGIN
FETCH ANO_1 INTO :ACCOUNTNUMBER, :SUBACCOUNTTYPE, :NAME;
END;
CATCH
IF $RC <> 100 THEN STOP ($RC, 'unexpected error');
IF (SUBACCOUNT_ID != ACCOUNT_ID) THEN BEGIN
IF SUBACCOUNTTYPE = 'CS' THEN BEGIN
TRY
DECLARE ANO_2 CURSOR FOR
SELECT ACCOUNT_ORDER, NAME
FROM KERN.CUSTOMER WHERE ID = :SUBACCOUNT_ID;
WHILE $RC = 0 DO BEGIN
FETCH ANO_2 INTO :ACCOUNTORDER, :NAME;
SET ACCOUNTNUMBER = ACCOUNTNUMBER || ACCOUNTORDER;
END;
CATCH
IF $RC <> 100 THEN STOP ($RC, 'unexpected error');
END;
IF SUBACCOUNTTYPE = 'PD' THEN BEGIN
TRY
DECLARE ANO_3 CURSOR FOR
SELECT ACCOUNT_ORDER, NAME
FROM KERN.PRODUCT WHERE ID = :SUBACCOUNT_ID;
WHILE $RC = 0 DO BEGIN
FETCH ANO_3 INTO :ACCOUNTORDER, :NAME;
SET ACCOUNTNUMBER = ACCOUNTNUMBER || ACCOUNTORDER;
END;
CATCH
IF $RC <> 100 THEN STOP ($RC, 'unexpected error');
END;
END;
RETURN ACCOUNTNUMBER;
END;
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Elke,
i retried using declared cursor, but still dont work, only works if i create an index for table balance on field account_id and use the hint INDEXACCESS to avoid the TABLE SCAN.
follow is the working SQL:
SELECT
/*+INDEXACCESS*/b.account_id,
VENDOR_CONCES.getAccountNumber(b.account_id,b.subaccount_id) account_number,
VENDOR_CONCES.getAccountName(b.account_id,b.subaccount_id) account_name
FROM balance b
WHERE
b.account_id = '00000001'
KR Clóvis
Hi Clovis,
I checked this on my Win32 Installation 7.7.02 Build 16 and it worked as it should.
So I think this is likely to be no limitation by design but probably a bug in that version.
Did you check it with a simpler function?
Anyhow there ARE already some known bugs entered into the bugtracking system (http://www.sapdb.org/webpts), also for MaxDB => 7.6.03.
So as long as there is no version with the fix available I'd try to rewrite the statemetns e.g. select the "decoded" data from a view.
KR Lars
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
93 | |
10 | |
10 | |
9 | |
9 | |
7 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.