mysql - 有没有比使用存储过程更好的方法?

标签 mysql stored-procedures coldfusion coldfusion-9 sendgrid

请考虑以下我用来获取 Sendgrid 发布的数据的代码。

<cftry>              
 <cfset incomingData = toString(getHttpRequestData().content) />
 <cfset djs = DeserializeJSON(incomingData)/>

<cfset a = "0">
<cfset b = "">
<cfset c = "0">
<cfset d = "0">
<cfset e = "">
<cfset f = "">
<cfset g = "">
<cfset h = "">
<cfset i = "">
<cfset k = "#NOW()#">
<cfset l = "">
<cfset m = "">
<cfset n = "">

<cfoutput>
<cfloop from="1" to="#arraylen(djs)#" index="i">

    <cfset a = "0">
    <cfset b = "">
    <cfset c = "0">
    <cfset d = "0">
    <cfset e = "">
    <cfset f = "">
    <cfset g = "">
    <cfset h = "">
    <cfset i = "">
    <cfset k = "#NOW()#">
    <cfset l = "">
    <cfset m = "">
    <cfset n = "">

    <cfif StructKeyExists(djs[i],'p')>
        <cfset a       = djs[i].p />
    </cfif>

    <cfif StructKeyExists(djs[i],'q')>
        <cfset b           = djs[i].q />
    </cfif>
    <cfif StructKeyExists(djs[i],'r')>
        <cfset c       = djs[i].r />
    </cfif>
    <cfif StructKeyExists(djs[i],'s')>
        <cfset d       = djs[i].s />
    </cfif>     
    <cfif StructKeyExists(djs[i],'t')>
        <cfset e       = djs[i].t />
    </cfif>
   <cfif StructKeyExists(djs[i],'u')>
        <cfset f           = djs[i].u />
    </cfif>
    <cfif StructKeyExists(djs[i],'v')>
        <cfset g       = djs[i].v />
    </cfif>

    <cfif StructKeyExists(djs[i],'w')>
        {                                                                         
        <cfset i  = djs[i].w />
        <cfset k  = dateAdd("s", i, createDateTime(1970, 1, 1, 0, 0, 0))/>
        }
    </cfif>
    <cfif StructKeyExists(djs[i],'x')>
        <cfset l         = djs[i].x />
    </cfif>
    <cfif StructKeyExists(djs[i],'y')>
        <cfset m       = djs[i].y />
    </cfif>
    <cfif StructKeyExists(djs[i],'z')>
        <cfset n       = djs[i].z /> 
    </cfif>

    <cfstoredproc procedure="sp1" datasource="db1">
        <cfprocparam cfsqltype="cf_sql_bigint" value="#a#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(b,199)#">
        <cfprocparam cfsqltype="cf_sql_integer" value="#c#">
        <cfprocparam cfsqltype="cf_sql_integer" value="#d#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(e,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(f,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(g,499)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(h,199)#">
        <cfprocparam cfsqltype="cf_sql_timestamp" value="#k#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(l,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#LEFT(m,499)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(n,99)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="XX.XX.X.XX">
    </cfstoredproc>


    <cfstoredproc procedure="sp2" datasource="db2">
        <cfprocparam cfsqltype="cf_sql_bigint" value="#a#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(b,199)#">
        <cfprocparam cfsqltype="cf_sql_integer" value="#c#">
        <cfprocparam cfsqltype="cf_sql_integer" value="#d#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(e,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(f,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(g,499)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(h,199)#">
        <cfprocparam cfsqltype="cf_sql_timestamp" value="#k#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(l,199)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#LEFT(m,499)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="#left(n,99)#">
        <cfprocparam cfsqltype="cf_sql_varchar" value="XX.XX.X.XX">
    </cfstoredproc>   

</cfloop>

</cfoutput>

</cftry>

从上面可以清楚地看出,我的代码依赖于 MySQL 数据库上的存储过程。我正在考虑摆脱存储过程并找到一种不同的方式来完成我正在寻找的事情而无需任何存储过程。除了使用存储过程将传入数据存储到数据库之外,还有更好的方法吗?

最佳答案

除了使用存储过程将传入数据存储到数据库之外,还有更好的方法吗? 不,不是。一个更好的问题是为什么您觉得有必要停止使用存储过程?

与数据库交互时,您实际上只有三个选项;存储过程、内联查询(参数化)或对象关系映射 (ORM)。当然,您可以用内联查询或 ORM 替换存储过程调用,但我认为您不会真正获得任何好处。

使用存储过程而不是内联查询的一些好处是:

  • Reduced server/client network traffic
    The commands in a procedure are executed as a single batch of code. This can significantly reduce network traffic between the server and client because only the call to execute the procedure is sent across the network. Without the code encapsulation provided by a procedure, every individual line of code would have to cross the network.

  • Stronger security
    Multiple users and client programs can perform operations on underlying database objects through a procedure, even if the users and programs do not have direct permissions on those underlying objects. The procedure controls what processes and activities are performed and protects the underlying database objects. This eliminates the requirement to grant permissions at the individual object level and simplifies the security layers.

    The EXECUTE AS clause can be specified in the CREATE PROCEDURE statement to enable impersonating another user, or enable users or applications to perform certain database activities without needing direct permissions on the underlying objects and commands. For example, some actions such as TRUNCATE TABLE, do not have grantable permissions. To execute TRUNCATE TABLE, the user must have ALTER permissions on the specified table. Granting a user ALTER permissions on a table may not be ideal because the user will effectively have permissions well beyond the ability to truncate a table. By incorporating the TRUNCATE TABLE statement in a module and specifying that module execute as a user who has permissions to modify the table, you can extend the permissions to truncate the table to the user that you grant EXECUTE permissions on the module.

    When calling a procedure over the network, only the call to execute the procedure is visible. Therefore, malicious users cannot see table and database object names, embed Transact-SQL statements of their own, or search for critical data.

    Using procedure parameters helps guard against SQL injection attacks. Since parameter input is treated as a literal value and not as executable code, it is more difficult for an attacker to insert a command into the Transact-SQL statement(s) inside the procedure and compromise security.

    Procedures can be encrypted, helping to obfuscate the source code. For more information, see SQL Server Encryption.

  • Reuse of code
    The code for any repetitious database operation is the perfect candidate for encapsulation in procedures. This eliminates needless rewrites of the same code, decreases code inconsistency, and allows the code to be accessed and executed by any user or application possessing the necessary permissions.

  • Easier maintenance
    When client applications call procedures and keep database operations in the data tier, only the procedures must be updated for any changes in the underlying database. The application tier remains separate and does not have to know how about any changes to database layouts, relationships, or processes.

  • Improved performance
    By default, a procedure compiles the first time it is executed and creates an execution plan that is reused for subsequent executions. Since the query processor does not have to create a new plan, it typically takes less time to process the procedure. If there has been significant change to the tables or data referenced by the procedure, the precompiled plan may actually cause the procedure to perform slower. In this case, recompiling the procedure and forcing a new execution plan can improve performance.

其中一些特定于 SQL Server,但大多数适用于任何数据库
Reference - Stored Procedures (Database Engine)

关于mysql - 有没有比使用存储过程更好的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25515947/

相关文章:

php - 无法从 PHP 连接到服务器 MySQL 服务器,但它在 phpmyadmin 中工作

php - 使用连接更新 sql

mysql - 如何从左连接中删除冗余字段

MySQL如何将字符串附加到磁盘上的外部文件?

postgresql - 如何在postgreSQL中出现异常后重试事务

php - PDO::ERRMODE_EXCEPTION 不抑制警告

sql - mysql @@identity 与 sql-server last_insert_id()

mod-rewrite - Mango 博客的 URL 重写问题(404 错误)

coldfusion - 更改 ColdFusion WEB-INF 库中的 JAR 文件

ajax - 在没有 View 的情况下仅在 FW1 中使用 Controller