DB2 stored procedure w/ parameters











up vote
2
down vote

favorite
2












I'm having a hard time producing the correct results from my stored procedure. I'm using a db2 database and I have 3 input parameters division, department, project. My call statement looks like this.



CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')


I need to produce results that will display the row of data when the third parameter is specified or has a value for the Project Name (as from the example above 'Online_fulfillment') and to display all the results when the third parameter has a value 'ALL' for Project Name (per the example below 'ALL').



CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')


My query below currently is returning just the column header names with no results and I'm having trouble debugging it. Here is my current stored procedure.



CREATE PROCEDURE schema.stored_procedure
(IN in_DIVISION_NAME VARCHAR(200)
,IN in_DEPARTMENT_NAME VARCHAR(20)
,IN in_PROJECT_NAME VARCHAR(400)
)
DYNAMIC RESULT SETS 1
BEGIN
IF (in_PROJECT_NAME = 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;

BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_DW_1;

OPEN exitCursor;

END;
END


EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')
enter image description here
EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')
enter image description here










share|improve this question
























  • Two things: 1) Why do you dump the results into a temp table, then open a new cursor and return all rows from the temp table (as opposed to just opening a cursor over the initial SELECT)? 2) This procedure actually appears amenable to being created as a view, which would likely be better able to use the optimizer in cases where you're joining to the results. Obviously, you couldn't supply parameters for the view, but it'd be trivial to supply them as a join condition/as part of a WHERE clause.
    – Clockwork-Muse
    May 20 '14 at 10:08















up vote
2
down vote

favorite
2












I'm having a hard time producing the correct results from my stored procedure. I'm using a db2 database and I have 3 input parameters division, department, project. My call statement looks like this.



CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')


I need to produce results that will display the row of data when the third parameter is specified or has a value for the Project Name (as from the example above 'Online_fulfillment') and to display all the results when the third parameter has a value 'ALL' for Project Name (per the example below 'ALL').



CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')


My query below currently is returning just the column header names with no results and I'm having trouble debugging it. Here is my current stored procedure.



CREATE PROCEDURE schema.stored_procedure
(IN in_DIVISION_NAME VARCHAR(200)
,IN in_DEPARTMENT_NAME VARCHAR(20)
,IN in_PROJECT_NAME VARCHAR(400)
)
DYNAMIC RESULT SETS 1
BEGIN
IF (in_PROJECT_NAME = 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;

BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_DW_1;

OPEN exitCursor;

END;
END


EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')
enter image description here
EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')
enter image description here










share|improve this question
























  • Two things: 1) Why do you dump the results into a temp table, then open a new cursor and return all rows from the temp table (as opposed to just opening a cursor over the initial SELECT)? 2) This procedure actually appears amenable to being created as a view, which would likely be better able to use the optimizer in cases where you're joining to the results. Obviously, you couldn't supply parameters for the view, but it'd be trivial to supply them as a join condition/as part of a WHERE clause.
    – Clockwork-Muse
    May 20 '14 at 10:08













up vote
2
down vote

favorite
2









up vote
2
down vote

favorite
2






2





I'm having a hard time producing the correct results from my stored procedure. I'm using a db2 database and I have 3 input parameters division, department, project. My call statement looks like this.



CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')


I need to produce results that will display the row of data when the third parameter is specified or has a value for the Project Name (as from the example above 'Online_fulfillment') and to display all the results when the third parameter has a value 'ALL' for Project Name (per the example below 'ALL').



CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')


My query below currently is returning just the column header names with no results and I'm having trouble debugging it. Here is my current stored procedure.



CREATE PROCEDURE schema.stored_procedure
(IN in_DIVISION_NAME VARCHAR(200)
,IN in_DEPARTMENT_NAME VARCHAR(20)
,IN in_PROJECT_NAME VARCHAR(400)
)
DYNAMIC RESULT SETS 1
BEGIN
IF (in_PROJECT_NAME = 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;

BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_DW_1;

OPEN exitCursor;

END;
END


EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')
enter image description here
EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')
enter image description here










share|improve this question















I'm having a hard time producing the correct results from my stored procedure. I'm using a db2 database and I have 3 input parameters division, department, project. My call statement looks like this.



CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')


I need to produce results that will display the row of data when the third parameter is specified or has a value for the Project Name (as from the example above 'Online_fulfillment') and to display all the results when the third parameter has a value 'ALL' for Project Name (per the example below 'ALL').



CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')


My query below currently is returning just the column header names with no results and I'm having trouble debugging it. Here is my current stored procedure.



CREATE PROCEDURE schema.stored_procedure
(IN in_DIVISION_NAME VARCHAR(200)
,IN in_DEPARTMENT_NAME VARCHAR(20)
,IN in_PROJECT_NAME VARCHAR(400)
)
DYNAMIC RESULT SETS 1
BEGIN
IF (in_PROJECT_NAME = 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;

BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_DW_1;

OPEN exitCursor;

END;
END


EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ONLINE FULFILLMENT')
enter image description here
EXPECTED RESULTS:
CALL schema.stored_procedure ('IT', 'MARKETING', 'ALL')
enter image description here







sql stored-procedures db2






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 20 '14 at 19:19









AngocA

6,49532648




6,49532648










asked May 19 '14 at 19:57









Tone

44261742




44261742












  • Two things: 1) Why do you dump the results into a temp table, then open a new cursor and return all rows from the temp table (as opposed to just opening a cursor over the initial SELECT)? 2) This procedure actually appears amenable to being created as a view, which would likely be better able to use the optimizer in cases where you're joining to the results. Obviously, you couldn't supply parameters for the view, but it'd be trivial to supply them as a join condition/as part of a WHERE clause.
    – Clockwork-Muse
    May 20 '14 at 10:08


















  • Two things: 1) Why do you dump the results into a temp table, then open a new cursor and return all rows from the temp table (as opposed to just opening a cursor over the initial SELECT)? 2) This procedure actually appears amenable to being created as a view, which would likely be better able to use the optimizer in cases where you're joining to the results. Obviously, you couldn't supply parameters for the view, but it'd be trivial to supply them as a join condition/as part of a WHERE clause.
    – Clockwork-Muse
    May 20 '14 at 10:08
















Two things: 1) Why do you dump the results into a temp table, then open a new cursor and return all rows from the temp table (as opposed to just opening a cursor over the initial SELECT)? 2) This procedure actually appears amenable to being created as a view, which would likely be better able to use the optimizer in cases where you're joining to the results. Obviously, you couldn't supply parameters for the view, but it'd be trivial to supply them as a join condition/as part of a WHERE clause.
– Clockwork-Muse
May 20 '14 at 10:08




Two things: 1) Why do you dump the results into a temp table, then open a new cursor and return all rows from the temp table (as opposed to just opening a cursor over the initial SELECT)? 2) This procedure actually appears amenable to being created as a view, which would likely be better able to use the optimizer in cases where you're joining to the results. Obviously, you couldn't supply parameters for the view, but it'd be trivial to supply them as a join condition/as part of a WHERE clause.
– Clockwork-Muse
May 20 '14 at 10:08












1 Answer
1






active

oldest

votes

















up vote
0
down vote













I believe I have solved this by adding an additional IF statement setting the in_PROJECT_NAME <> 'ALL' and adding an additional filter to the second query that sets the PROJECT_NAME = in_PROJECT_NAME. Could be an easier way to solve this but it works:



IF (in_PROJECT_NAME <> 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME ,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;
AND PROJECT_NAME = in_PROJECT_NAME





share|improve this answer



















  • 1




    Your solution seems good, however if you have many cases, and each time you need to copy the same select, then the best is to use a dynamic query (prepare, execute).
    – AngocA
    May 20 '14 at 6:20










  • Can you provide me with an example?
    – Tone
    May 20 '14 at 14:18











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f23746173%2fdb2-stored-procedure-w-parameters%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













I believe I have solved this by adding an additional IF statement setting the in_PROJECT_NAME <> 'ALL' and adding an additional filter to the second query that sets the PROJECT_NAME = in_PROJECT_NAME. Could be an easier way to solve this but it works:



IF (in_PROJECT_NAME <> 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME ,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;
AND PROJECT_NAME = in_PROJECT_NAME





share|improve this answer



















  • 1




    Your solution seems good, however if you have many cases, and each time you need to copy the same select, then the best is to use a dynamic query (prepare, execute).
    – AngocA
    May 20 '14 at 6:20










  • Can you provide me with an example?
    – Tone
    May 20 '14 at 14:18















up vote
0
down vote













I believe I have solved this by adding an additional IF statement setting the in_PROJECT_NAME <> 'ALL' and adding an additional filter to the second query that sets the PROJECT_NAME = in_PROJECT_NAME. Could be an easier way to solve this but it works:



IF (in_PROJECT_NAME <> 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME ,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;
AND PROJECT_NAME = in_PROJECT_NAME





share|improve this answer



















  • 1




    Your solution seems good, however if you have many cases, and each time you need to copy the same select, then the best is to use a dynamic query (prepare, execute).
    – AngocA
    May 20 '14 at 6:20










  • Can you provide me with an example?
    – Tone
    May 20 '14 at 14:18













up vote
0
down vote










up vote
0
down vote









I believe I have solved this by adding an additional IF statement setting the in_PROJECT_NAME <> 'ALL' and adding an additional filter to the second query that sets the PROJECT_NAME = in_PROJECT_NAME. Could be an easier way to solve this but it works:



IF (in_PROJECT_NAME <> 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME ,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;
AND PROJECT_NAME = in_PROJECT_NAME





share|improve this answer














I believe I have solved this by adding an additional IF statement setting the in_PROJECT_NAME <> 'ALL' and adding an additional filter to the second query that sets the PROJECT_NAME = in_PROJECT_NAME. Could be an easier way to solve this but it works:



IF (in_PROJECT_NAME <> 'ALL') THEN
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_DW_1
(DIM_PROJECT_ID INT
,PROJECT_NAME VARCHAR (400)
,DIM_DEPARTMENT_ID INT
,DEPARTMENT_NAME VARCHAR(100)
,DIVISION_NAME VARCHAR(100)
) ON COMMIT DELETE ROWS NOT LOGGED WITH REPLACE;
END;

INSERT INTO SESSION.TEMP_DW_1 (DIM_PROJECT_ID, PROJECT_NAME, DIM_DEPARTMENT_ID,
DEPARTMENT_NAME ,DIVISION_NAME)
SELECT DISTINCT DJ.DIM_PROJECT_ID
,PROJECT_NAME
,DIM_DEPARTMENT_ID
,DEPARTMENT_NAME
,DIVISION_NAME
FROM SCHEMA.FACT_TABLE
WHERE DEPARTMENT_NAME = in_DEPARTMENT_NAME
AND DIVISION_NAME = in_DIVISION_NAME;
AND PROJECT_NAME = in_PROJECT_NAME






share|improve this answer














share|improve this answer



share|improve this answer








edited May 20 '14 at 19:16









AngocA

6,49532648




6,49532648










answered May 19 '14 at 21:43









Tone

44261742




44261742








  • 1




    Your solution seems good, however if you have many cases, and each time you need to copy the same select, then the best is to use a dynamic query (prepare, execute).
    – AngocA
    May 20 '14 at 6:20










  • Can you provide me with an example?
    – Tone
    May 20 '14 at 14:18














  • 1




    Your solution seems good, however if you have many cases, and each time you need to copy the same select, then the best is to use a dynamic query (prepare, execute).
    – AngocA
    May 20 '14 at 6:20










  • Can you provide me with an example?
    – Tone
    May 20 '14 at 14:18








1




1




Your solution seems good, however if you have many cases, and each time you need to copy the same select, then the best is to use a dynamic query (prepare, execute).
– AngocA
May 20 '14 at 6:20




Your solution seems good, however if you have many cases, and each time you need to copy the same select, then the best is to use a dynamic query (prepare, execute).
– AngocA
May 20 '14 at 6:20












Can you provide me with an example?
– Tone
May 20 '14 at 14:18




Can you provide me with an example?
– Tone
May 20 '14 at 14:18


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f23746173%2fdb2-stored-procedure-w-parameters%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Tangent Lines Diagram Along Smooth Curve

Yusuf al-Mu'taman ibn Hud

Zucchini