I am trying to execute an sql statement by receiving a dynamic table.
If #{} is used, sql does not work because it is entered in the form of'layer_name'.
Therefore, I have to use ${}, but there is a problem that is vulnerable to sql injection.
<select id="test" parameterType="map" resultType="map">
select
*
from
${table_name}
</select>
I want to use a procedure to solve this problem, but the return type is ambiguous because I have to do 'select all'.
Any ideas would be appreciated.
Related
I am trying to dynamically include select query based on some input parameters.
The following is what I am trying to achieve.
<sql id="query1">
SELECT * from
table_1
WHERE a = #{param1}
</sql>
<sql id="query2">
SELECT * from
table_2
WHERE b = #{param2}
</sql>
<select id = "selectSomethingFromDB">
<include refid="#{readerIdName}" />
</select>
I am planning to pass the sql id name as parameter to the query and trying to dynamically choose the select query based on this param. (Sort of like a factory design implementation).
However #{readerIdName} is not getting replaced with the value I am passing as param.
Is something like this possible?
The xml attributes at this level are not evaluated in runtime by mybatis.
You can use a single <SQL id="..."> query and an <if test="..."> dynamic sql in it.
The operative goal is to be able to compare an ID to a provided list passed in text form, e.g. "1,2,3,4,5." The thought was to simply use string_to_array to convert the input to an array and use the ANY operator on it. The issue arises because of Liquibase, when compiling the code an unexpected error occurs:
[ERROR] Unable to execute the query: {call testfunction(?)}
org.postgresql.util.PSQLException: ERROR: invalid input syntax for type integer: "str286"
Where: SQL statement "select string_to_array(id_list, ',')::int[]"
PL/pgSQL function testfunction(character varying) line 10 at SQL statement
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440) ~[dao-generator.jar:?]
The code that generated the error is as follows:
CREATE OR REPLACE FUNCTION TestFunction
(
IN id_list VARCHAR(8000)
)
RETURNS TABLE
(
ID INT
)
AS
$$
DECLARE
my_array int[4];
BEGIN
select string_to_array(id_list, ',')::int[] into my_array;
RETURN QUERY
SELECT myTable.id
FROM myTable
WHERE myTable.parent_id = ANY(my_array);
END
$$
LANGUAGE plpgsql;
My question is how to resolve this error? Granted I am not much of a database programmer so if someone wants to recommend an alternative approach, that is also welcome.
Edits:
The call is executed as part of a liquibase compilation the changelog entries are
create_procedures entry:
<changeSet author="-" id="-" runAlways="true" runInTransaction="true">
<validCheckSum>any</validCheckSum>
<comment>Create TestFunction stored procedure.</comment>
<sqlFile dbms="postgresql" path="-/-/-/TestFunction.sql"
encoding="UTF-8"
relativeToChangelogFile="true"
endDelimiter="go"
splitStatements="true"/>
</changeSet>
GeneratorConfig entry:
<query name="TestFunction"/>
So after some brainstorming with the feedback from #a_horse_with_no_name, a coworker came up with a simple enough solution to get through the build process. We simply did a regex check on the input to make sure it was formatted as expected (probably not a bad idea anyway) and then altered the query according to #a_horse_with_no_name's comment.
This doesn't really answer why liquibase was testing with strings in the form of strXYZ but does at least provide a workaround in this situation
My project is a Database center, like PLSQL but used in a web browser. Sometimes I need to create or alter a table, but I don't know if Mybatis supports DDL, and I haven't found any documents about this.
For the most part DDL works just like DML using mybatis. The one difference is that you will need to use ${} instead of #{} for parameters. Most databases do not support prepared statements with DDL. The $ notation is a string substitution rather than a parameter for a prepared statement.
<update id="exchangePartition" parameterType="java.util.Map">
alter table ${destinationTableName}
exchange partition ${destinationPartitionName}
with table ${sourceTableName}
including indexes
with validation
</update>
It is also helpful to know the call syntax with the statement type callable to invoke stored procedures.
<update id="gatherStatistics" statementType="CALLABLE" parameterType="Map">
{call
dbms_stats.gather_table_stats(
ownname => #{tableOwner},
tabname => #{tableName}
<if test="partitionName != null">
, partname => #{partitionName}
</if>
)
}
</update>
MyBatis supports any native SQL/PlSql commands.
So yes, it supports DDL statements.
Currently my development environment is using SQL server express 2008 r2 and VS2010 for my project development.
My question is like this by providing a scenario:
Development goal:
I develop window services something like data mining or data warehousing using .net C#.
That meant I have a two or more database involved.
my senario is like this:
I have a database with a table call SQL_Stored inside provided with a coloum name QueryToExec.
I first idea that get on my mind is written a stored procedure and i tried to came out a stored procedure name Extract_Sources with two parameter passed in thats ID and TableName.
My first step is to select out the sql need to be execute from table SQL_Stored. I tried to get the SQL by using a simple select statement such as:
Select Download_Sql As Query From SQL_Stored
Where ID=#ID AND TableName=#TableName
Is that possible to get the result or is there another way to do so?
My Second step is to excecute the Sql that i get from SQL_Stored Table.Is possible to
to execute the query that select on the following process of this particular stored proc?
Need to create a variable to store the sql ?
Thank you,Appreciate for you all help.Please don't hesitate to voice out my error or mistake because I can learn from it. Thank you.
PS_1:I am sorry for my poor English.
PS_2:I am new to stored procedure.
LiangCk
Try this:
DECLARE #download_sql VARCHAR(MAX)
Select
#download_sql = Download_Sql
From
SQL_Stored
Where
AreaID = #AreaID
AND TableName = #TableName
EXEC (#download_sql)
I want to execute a T-SQL statement with ADO-layer. The sql-statement is like:
DECLARE #var TABLE (id int)
INSERT INTO #var SELECT id FROM tblFoo WHERE name='myName' AND idx=2
SELECT * FROM tblFoo WHERE id IN (SELECT * FROM #var)
In the SQL Server management console all works well. But if I use that for opening a ADO_Recordset via Open(sql) that recordset will not be filled/opened. eof() said: recordset is not opened.
The question ist: How to exectue T-SQL stataments that will result a recordset on the ADO layer?
In the Options parameter of the Open() method you need to pass in CommandTypeEnum.adCmdText.
see this link for more info http://msdn.microsoft.com/en-us/library/ms675544(v=vs.85).aspx
Also change your query to this:
SELECT * FROM tblFoo WHERE name='myName' AND idx=2
You need to treat this SQL as plain test
something like:
cmd.CommandType = adCmdText