Selecting multiple rows a table according to rows passed with a table valued parameter
Ive got a table, which looks like this:
CREATE TABLE MyTable (
MyChars CHAR(3) NOT NULL,
MyId INT NOT NULL,
CONSTRAINT PK__MyTable_MyChars_MyId PRIMARY KEY (MyChars, MyId),
CONSTRAINT FK__MyOtherTable_Id_MyTable_MyId FOREIGN KEY (MyId) REFERENCES MyOtherTable (Id)
Records look like i.e.:
Chars | Id
'AAA' | 1
'BBB' | 1
'CCC' | 1
'AAA' | 2
'BBB' | 2
'CCC' | 2
'DDD' | 2
'EEE' | 3
'FFF' | 3
'AAA' | 4
'DDD' | 4
'FFF' | 4
Now I have a SP, which takes a table valued parameter like:
CREATE TYPE dbo.MyTVP AS TABLE ( MyChars CHAR(3) )
This SP should return a set of Ids, which match all the rows of the parameter.
I.e.:
if the TVP contains 'AAA', 'BBB' & 'CCC', i get as result 1 & 2
if the TVP contains 'AAA' & 'FFF', i get as result 4
if the TVP contains 'BBB' & 'EEE', i get an empty result
What my SP is currently doing, is to build a query with string concatination, which is then executed with the EXEC statement. If we take my first example, the built query would look like this:
SELECT DISTINCT t0.MyId
FROM MyTable t0
INNER JOIN MyTable t1 ON t0.MyId = t1.MyId
INNER JOIN MyTable t2 ON t1.MyId = t2.MyId
WHERE t0.MyChars = 'AAA' AND t1.MyChars = 'BBB' AND t2.MyChars = 'CCC'
It works, but I'm not very fond of building the query. Maintaining such things is always a pain. And it also might not be the most efficient and elegant way to do this.
Since I can't think of any other way of doing this, I wanted to ask, if someone of you got an idea, if there is a better way to accomplish this.
Let me give you a "cut and paste" I use in the SQL Server groups:
1) The dangerous, slow kludge is to use dynamic SQL and admit that any random future user is a better programmer than you are. It is used by Newbies who do not understand SQL or even what a compiled language is. A string is a string; it is a scalar value like
any other parameter; it is not code. Again, this is not just an SQL problem; this is a basic misunderstanding of programming principles.
2) Passing a list of parameters to a stored procedure can be done by putting them into a string with a separator. I like to use the traditional comma. Let's assume that you have a whole table full of such parameter lists:
CREATE TABLE InputStrings
(keycol CHAR(10) NOT NULL PRIMARY KEY,
input_string VARCHAR(255) NOT NULL);
INSERT INTO InputStrings
VALUES ('first', '12,34,567,896'),
('second', '312,534,997,896'),
etc.
This will be the table that gets the outputs, in the form of the original key column and one parameter per row.
It makes life easier if the lists in the input strings start and end with a comma. You will need a table of sequential numbers -- a standard SQL programming trick, Now, the query,
CREATE VIEW ParmList (keycol, place, parm)
AS
SELECT keycol,
COUNT(S2.seq), -- reverse order
CAST (SUBSTRING (I1.input_string
FROM S1.seq
FOR MIN(S2.seq) - S1.seq -1)
AS INTEGER)
FROM InputStrings AS I1, Series AS S1, Series AS S2
WHERE SUBSTRING (',' + I1.input_string + ',', S1.seq, 1) = ','
AND SUBSTRING (',' + I1.input_string + ',', S2.seq, 1) = ','
AND S1.seq < S2.seq
GROUP BY I1.keycol, I1.input_string, S1.seq;
The S1 and S2 copies of Series are used to locate bracketing pairs of commas, and the entire set of substrings located between them is extracted and cast as integers in one non-procedural step. The trick is to be sure that the right hand comma of the bracketing
pair is the closest one to the first comma. The relative position of each element in the list is given by the value of "place", but it does a count down so you can plan horizontal placement in columns.
This might be faster now:
WITH Commas(keycol, comma_seq, comma_place)
AS
(SELECT I1.keycol, S1.seq,
ROW_NUMBER() OVER (PARTITION BY I1.keycol ORDER BY S1.seq)
FROM InputStrings AS I1, Series AS S1
WHERE SUBSTRING (',' || I1.input_string || ','
FROM S1.seq
FOR 1) = ','
AND S1.seq <= CHARLENGTH (I1.input_string))
SELECT SUBSTRING(',' || I1.input_string || ','
FROM C1.comma_place +1
FOR C2.comma_place - C1.comma_place - 1)
FROM Commas AS C1, Commas AS C2
WHERE C2.comma_seq = C1.comma_seq + 1
AND C1.keycol = C2.keycol;
The idea is to get all the positions of the commas in the CTE and then use (n, n+1) pairs of positions to locate substrings. The hope is that the ROW_NUMBER() is faster than the GROUP BY in the first attempt. Since it is materialized before the body of
the query (in theory), there are opportunities for parallelism indexing and other things to speed up the works.
Hey, I can write kludges with the best of them, but I don't. You need to at the very least write a routine to clean out blanks, handle double commas and non-numerics in the strings, take care of floating point and decimal notation, etc. Basically, you must
write part of a compiler in SQL. Yeeeech! Or decide that you do not want to have data integrity, which is what most Newbies do in practice altho they do not know it.
A procedural loop is even worse. You have no error checking, no ability to pass local variables or expressions, etc.
CREATE PROCEDURE HomemadeParser(@input_string VARCHAR(8000))
AS
BEGIN
DECLARE @comma_position INTEGER;
CREATE TABLE #Slices
(slice_value INTEGER);
SET @input_string = @input_string + ','; --add sentinel comma
SET @comma_position = CHARINDEX(',', @input_string);
WHILE @comma_position > 1
BEGIN
INSERT INTO #Slices (slice_value)
VALUES(CAST(LEFT(@input_string, (@comma_position - 1)) AS INTEGER));
SET @input_string = RIGHT(@input_string, LEN(@input_string)-@comma_position)
SET @comma_position = CHARINDEX(',', @input_string)
END;
END;
Better answer:
http://www.simple-talk.com/sql/learn-sql-server/values()-and-long-parameter-lists/
http://www.simple-talk.com/sql/learn-sql-server/values()-and-long-parameter-lists---part-ii/
Do this with a long parameter list. You can pass up to 2000+ parameters in T-SQL, which is more than you probably will ever need. The compiler will do all that error checking that the query version and the procedural code simply do not have unless you write
a full parser with the standard error codes. You can now pass local variables to your procedure; you can pass other data types and get automatic conversions, etc. In short, this is just good software engineering.
CREATE PROCEDURE LongList
(@p1 INTEGER = NULL,
@p2 INTEGER = NULL,
@p3 INTEGER = NULL,
@p4 INTEGER = NULL,
@p5 INTEGER = NULL)
x IN (SELECT parm
FROM (VALUES (@p1), (@p2), (@p3), (@p4), (@p5)) AS X(parm)
WHERE parm IS NOT NULL;
You get all the advantages of the real compiler and can do all kinds of things with the values.
--CELKO-- Books in Celko Series for Morgan-Kaufmann Publishing: Analytics and OLAP in SQL / Data and Databases: Concepts in Practice Data / Measurements and Standards in SQL SQL for Smarties / SQL Programming Style / SQL Puzzles and Answers / Thinking
in Sets / Trees and Hierarchies in SQL
Similar Messages
-
Select multiple boxes at time of Outbound Delivery processing with scanner
Hi all,
I am facing a problem at time of processing outbound delivery. I am bound to select 1 box and its corresponding HU. This reduces productivity of end users. I want to know if there is any possibility to select multiple boxes at one go using a scanner, so as to attach all HU at same time.
Regards,
AjayHi,
This is because plant 2 is processing delivery -2 with reference to sales order.
So when you want to process deliver -1 then same already created with reference to sales order. it means both delivery cant be accessed one time because reference is sales order, so it lock
If you want to pick both at same time,
Then assign one shipping point to both plants, so when you create delivery both item will copy in delivery,then pick both at same time.
kapil -
Right way to preserve all parent table entries in a join with many tables!!
This problem is quite interesting to me. I have asked this question to others but no body is able to provide me with proper answers.
The problem is: How do I join a huge parent table with many child tables (more than 5 child tables) preserving all of the parent table entries. Lets say there is the parent table parentTable and three child tables childTable1, childTable2, childTable3. In order to get the data after joining these tables the query that I have been using was:
select parent.field1, parent.field2, parent.field3, child1.field4, child1.field5, child2.field6, child3.field7 from ParentTable parent, childTable1 child1, childTable1 child2, childTable3 child3 where parent.fielda = child1.fieldb and parent.fieldc = child.fieldd and parent.fielde = child.fieldf.
Although the tables are huge (more than 100,000 entries), this query is very fast, however those parent table entries which do not have child entries are lost. I know that I can left join a parent table with a child table and then with the next child table and then with the next child table and continue. Isn't there a simple solution for this commonly happening problem?
Please provide suggestions please...Hello Lakshmi,
Although I do not know exactly how to achieve what you want to achieve but I have seen DBAs/ABAPers in my experience can run queries/scripts using the COUNT function to give the actual number of line items per table for all your 100 or odd tables.
Rgds
CONMJI -
Sun java Creator, Table component vanishes when associating with the table
I am trying to develop JSF page with a table component and associating a table (users) to the table component.
I have created datasource and i can see the data in the SQL editor in Sun Java Creator.
But when i try to associate the table component with the table(users).
I table component vanishes.
I dont understand what is the problem.
Can anybody help me.The default theme is localized. If you look at <Creator-install>/rave2.0/modules/ext/locale
you should see the localized default theme jars. Not sure which locale you are. You can put your localized jar here. Add the localized jar to your web application via library manager for it to be included in the deployed war file
- Winston
http://blogs.sun.com/winston -
How to find the table relationship between BSEG-BELNR with CE11000 table.
Hi,
Please help me to find out the table relationship between BSEG with CE11000 table.
I have BSEG-BELNR value.
Thanks in Advance
ShankarHello,
BAsically the relationship can be foundon the basis of cost centre it will be good if you paste the structure ce11000.
I have worked on it and as far i as i can recall it contain value fields right...like vv205,vv305 etc?
Provide me more details.
Are you preparing some reconcillation report for costing based COPA or Account based COPA..?
Hopefully will help you out..
Regards,
Nabheet -
Updating Z table according ALV rows
Hi All!
I'm updating several columns automatically in ALV grid rows into Z database (current user name, date and hour). However, when I change only one row, all existed rows on the list are updated.
How can I update only the changed data in ALV?
ps.: it's used REUSE_ALV_GRID_DISPLAY FM.
Points will be rewarded!
Michel KhouriHi,
May this way.
i_backupoutput[] = i_grpoutput[]. " <<< copy output table to temp table
call function 'REUSE_ALV_GRID_DISPLAY'
exporting
it_fieldcat = pt_grpfcat[]
it_excluding = p_grpexcltab2[]
is_layout = pt_grplayout2
i_callback_program = sy-repid
i_callback_html_top_of_page = p_header
i_callback_pf_status_set = v_status_set1
i_callback_user_command = v_user_command1
i_screen_start_column = 25
i_screen_start_line = 5
i_screen_end_column = 80
i_screen_end_line = 20
it_events = i_events[]
tables
t_outtab = i_grpoutput.
form f_user_command1 using p_ucomm type sy-ucomm
rs_selfield type slis_selfield.
data p_ref1 type ref to cl_gui_alv_grid.
call function 'GET_GLOBALS_FROM_SLVC_FULLSCR'
importing
e_grid = p_ref1.
call method p_ref1->check_changed_data.
case p_ucomm.
when 'SAVE'.
loop at i_grpoutput.
read table i_backupoutput index sy-tabix.
if sy-subrc eq 0.
if i_grpoutput ne i_backupoutput.
<<<<<<< Update the record to Z table>>>>>>>>>
endif.
endif.
endlloop.
leave to screen 0.
endcase.
rs_selfield-refresh = c_x. " Grid refresh
endform. " F_user_command1
aRs
Message was edited by:
a® -
Selecting multiple records from the list and append it into internal table.
hi
there is a list of 10 records in the output screen with check boxes. if the user select any 3 records then those records should get appended in some other internal table of same structure.
this is the requirement. can anybody help me it is very urgent.
regards
samiHi,
Loop at the internal table which contains the value in table control and move it to a work area. apend the work area to the next internal table. Like:
loop at it1 into wa1 where sel = 'X'.
append wa1 to it2.
endloop.
or
loop at it1 into wa1.
if wa1-sel = 'X'.
append wa1 to it2.
endif.
endloop.
Regards,
RM -
Parse XML document ,create table according to tags & load data to table
Hi All!
I have one of the most common problem, one faces when dealing with xml stuff and oracle.I get xml documents, with each file having different tags.I want to write a pl/sql procedure such that, the xml file is parsed, a table is created with the tag names becoming the column names and all the nodes' data get inserted into the table as rows.I am using oracle 10g.
I read a thread at the following url:
Parse XML and load into table
But did not get much of it.
Can anybody please tell me how to accomplish this.
Thanking in advance.
Regards,
Deepika.Why do people have such an aversion to the XML DB forum for XML questions...
See FAQ for XML DB forum here: XML DB FAQ
Explains all about getting XML into tables in the database. -
Excise table J_1IEXCDTL not getting updated with Excise Base value.
Hi All,
The the field EXBAS of table J_1IEXCDTL is not getting updated for ETT (Transaction Type) DLFC.
For other transaction types, the same is getting populated.
Is there a setting for controlling the same?
If yes, can you please guide me.
Best Regards
Debaditya GhoshFirst you should ensure that it is flowing in your billing document. If so, automatically, it will also flow in your excise invoice and the field EXBAS will be updated accordingly.
From your comments, it seems, the amount is not flowing in your billing document and excise invoice. If so, ensure that you have assigned the correct tax code in FV11 for your ED condition type.
thanks
G. Lakshmipathi -
To find the tables which is having link with particular table.
hi all,
i am working on db 10g.
i have table called JOB_HEADER
My task is to delete the data in the job_header table.
Before doing this task, i want to know which are the tables referencing this particular table.
in other words i have to delelete child records first then i have to delete the above said table.
is there any way to know the child table existance for this particular parent table?
Thanks..GD wrote:
hi all,
i am working on db 10g.
i have table called JOB_HEADER
My task is to delete the data in the job_header table.
Before doing this task, i want to know which are the tables referencing this particular table.
in other words i have to delelete child records first then i have to delete the above said table.
is there any way to know the child table existance for this particular parent table?
Thanks..If there is properly declared referrential integrity declared then yes.
select *
from all_constraints
where r_constraint_name = (select constraint_name from all_constraints where table_name = 'JOB_HEADER' and constraint_type = 'P')
and constraint_type = 'R'Should do it.
Cheers, -
NodeJS Table Storage where clause prefix with numeric string value
I am looking to make a TableQuery that returns results where a string property starts with a number. I have attempted to use the same prefix method
described on the MSDN but I cannot get any results returned when the characters are numeric.
Here is an example of what I'm trying to do:
titleQuery = new azure.TableQuery()
.and 'title ge ?', '1'
.and 'title lt ?', '2'
Sample title values are "1-something", "something", and "123-something"
Looking at the comments in source, I can see that the query API has been updated, but don't see any examples of doing queries based on prefix.
Any thoughts on how or if this is possible?
David Wesst | MVP http://davidwesst.com | @davidwesstReceived a reply on the GitHub issues site, where I asked the same question.
It appears the issue was a simple oversight by me where I used two '.and' operators instead of a '.where' and an '.and'.
https://github.com/Azure/azure-storage-node/issues/30#issuecomment-61926225
Thanks!
David Wesst | http://davidwesst.com | @davidwesst -
How do you select multiple files on a macbook pro?
Can anyone tell me how to select multiple files at one time? I am so frustrated with the way macbook pro works that I really regret buying it. I hate that you can't select multiple files, and that my contact stuff keeps changing. It is certainly not like I was told...that I would never want to use a PC again. I would not buy another apple computer. I spent a lot of money to NOT be able to do things that I have always done with ease. Every time I think I have something figured out, it doesn't work the next time I go to use it in another program. If anyone has an answer to this, I would sure appreciate it.
And all of these so called wonderful updates to the operating system on all mac products have left me frustrated and liking my apple products far less than I did before. On my iphone I had to make the texts just huge to even be able to see the white writing on a blue background. Not sure who made these designs, but from my perspective, I can tell you they certainly weren't thinking about being user friendly in any way when they did it. So disappointed in all of my devices! I do not enjoy using my computer, ipad, or iphone even close to what I did before.This is some information on the Finder.
http://support.apple.com/kb/ht2470
To select multiple files you can use the shift key with the mouse if they are in a contiguous list or the CMD key with the mouse if you have breaks in that list. You can also use the mouse to drag over the files you want to select.
The Macs are easy to use, I have used many versions of Windows, Linux and other operating systems and I find OS X is far the easiest, but that is me.
There are many instructional videos and texts on Apples web site and if you are near to an Apple store they do classes to help.
Hope you get used to it. -
Downloaded ML last night now one little glitch seems to be that I cannot select multiple messages at a time to delete. With the massive amount of email I receive, this is a problem. Cannot seem to find any simple fixes in preferences. Any ideas?
you could use one hand to do this, before ML. select one email and drag up/down with the cursor to select more. selecting/shift key is the normal multiple selection operation. that's two handed.
if there is empty space at the bottom, it works.
i did submit this through the feedback process. i hope the functionality returns. -
How to achive multi-line editing (CRUD) with a table-UI on a ejb-model
Hello community,
i'm working on an prototype. we want to migrate an existing web-application to nw 7.1 with web-dynpro as ui-technology. the old application often uses javascript-/ajax- driven table-grid-controls. this table controls allowed editing the data in it. the conrol "records" every action. for example which rows were deleted, which were updated and which were appended.
when the user has finished editing, he simply clicks a save-button. the table-grid control then sends the changes via ajax-calls to the server.
now i want the achive such behavior in web-dynpro (7.1)
for getting the data to be edited, i wrote an ejb and created an ejb-model in web-dynpro. so viewing the data works fine so far. the view-controller with the table-ui-element is bound to the view-controllers context, which is mapped to the context-controller to which again a model-object is bound, which retrieves the data from the ejb.
inserting, updating and deleting single rows with a detail-view-controller also works, using additional context nodes (again mapped to addtional model-classes for crudp.
but i know want to have all rows and cells to be editable. the user should be able to insert, update and delete in that table without neccessarily using a detail-view-controller.
how would you achive this? holding every creates, update, deletes in single nodes? and when clicking a button to fire the save action to go to that nodes and apply that action? Or would you create an addtional flag-attribute in the node that shows what was done with that row? after pressing save also iterating the nodes, checking for the flag and doing the appropriate actions (but this maybee is performance critical when having a lot of rows)?
any ideas how to achieve multiple crud-operations on a context-node, viewed with a table-ui-element would be welcome.
regards
MatthiasMatthias,
Let's address your questions one by one.
1. You can make the table cells editable by chosing 'InputField' as TableCellEditor.
2. Since you have bound your table to 'View Context' and 'View Context' to 'Component Context', all changes made by you in table will be visible in Component Context after every round-trip to server.
3. To modify the data in 'backend', you need to modify your 'Save' method to check for every changed element and modify the data only if element was changed by user. To see if the element has been changed by user, use [IWDNodeElement.isChangedByClient()|https://help.sap.com/javadocs/NW04S/current/wd/com/sap/tc/webdynpro/progmodel/api/IWDNodeElement.html] method. This method returns true if element was changed by user - this is what you need.
To learn more about WD Table UI element, you may want to see [this link|http://help.sap.com/saphelp_nw70/helpdata/en/eb/220a415a47f06fe10000000a1550b0/frameset.htm].
Hope this helps.
Vishwas. -
Finding duplicates:Minus set operator in dealing with internal tables
Dear experts,
I am newbie to ABAP developement,i have been given an assignment to find the duplicate list of vendors in lfa table.
Now duplicate list doesnot means that text tokens will be just exact to conclude them as duplicate ,it could also be like
1111 Vendor ABC
1222 ABC Vendor
If anybody has clue ,how to work on such a problem ,plz come forward.
Right now i just tried initially how to find exact duplicates,i found on change command,it do works.
Then i am trying a new way which should just do the same thing.
I did as per this algorithm
1.Compute wholesome list in one internal table itab1
2.Used delete adjacent duplicates in itab2.
3.I feel itab3=itab1-itab2 will contain all duplicates in itab3.
Can anyone give me a hint.How can i do A-B ?.Hi Arul,
There is no special aided SET operations upon internal tables in ABAP. Concerning your particular task I would say that you can try INSERT statement for each record in your internal table without preliminary comparing them with DB table. If there is a record in DB table with the same key then sy-subrc after INSERT will be non zero (actually 4) and no real insert would occur. So, only those records would be inserted which have no counterpart in DB table.
Best regards, Sergei
Maybe you are looking for
-
I have a web page that contains a ReportViewer control. I am trying to display a report, which is an .rdl file located on the SSRS server, in this ReportViewer control. I have set the ReportPath and ReportServerUrl correctly. I am getting an error
-
Transfer Pricing Utilizing Third Local Currency in Company Code?
I was wondering whether utilizing the third local currency under the "Additional Local Currencies for Company Code" section of the IMG would not allow you to use Supply Chain going forward because that third local currency must be saved for Transfer
-
The title basically says it all... I'm setting up this iPod Touch for my grandparents, and am trying to make it as simple as possible, so I'd like to remove applications they won't use like calculator, stocks, and maps... I tried holding down on an a
-
Get javascript variable in JSP
Hi all, can anybody tell me- how to get javascript variable in JSP, in the same file (JSP). Is this possible. I can use JavaScript to get the value, but then I have no way to get that to the JSP code. Please give the appripriate answer with code. Tha
-
In Utlra Dev I would Insert Layer and although layers are anything by WYSIWYG in design view, once you got them where you want them they would stay right there. Looking at the code you see "absolute position" and the coordinates etc In my shiny new (