Проверьте, отличается ли какое-либо поле от значения базы данных - PullRequest
1 голос
/ 10 июня 2019

После отправки формы мне нужно проверить, изменилось ли какое-либо поле в таблице базы данных. Если меняли, я создаю новую запись, если нет, я ничего не делаю. Я не могу просто обновить запись.

Есть ли способ сделать это, не проверяя каждое поле, как в коде ниже?

<cfquery name="getData" datasource="myDS">
  Select * From table Where ID = #form.ID#
</cfquery>
<Cfset changed = false />
<!-- Check every field -->
<cfif form.data1 neq getData.data1>
   <cfset changed = true />
</cfif>
<cfif form.data2 neq getData.data2>
   <cfset changed = true />
</cfif>
<cfif form.data3 neq getData.data3>
   <cfset changed = true />
</cfif>
...

Спасибо

Ответы [ 3 ]

3 голосов
/ 10 июня 2019

Может зависеть от того, какую базу данных вы используете, но вы сможете выполнить запрос, который будет вставлен, если данных не существует.

В качестве примера я только что проверил это на Oracle 12c с использованием CF2016 Enterprise, и он создает новую запись, если данных не существует.

<cfquery name="Testing" datasource="Test">
    INSERT INTO TESTTABLE (DATA1, DATA2, DATA3)
    SELECT  <cfqueryparam value="#Form.Data1#" cfsqltype="CF_SQL_VARCHAR" />, <cfqueryparam value="#Form.Data2#" cfsqltype="CF_SQL_VARCHAR" />, <cfqueryparam value="#Form.Data3#" cfsqltype="CF_SQL_VARCHAR" />
    FROM dual
    WHERE NOT EXISTS 
    (SELECT DATA1, DATA2, DATA3 FROM TESTTABLE WHERE DATA1 = <cfqueryparam value="#Form.Data1#" cfsqltype="CF_SQL_VARCHAR" />, 
    AND DATA2 = <cfqueryparam value="#Form.Data2#" cfsqltype="CF_SQL_VARCHAR" /> AND DATA3 = <cfqueryparam value="#Form.Data3#" cfsqltype="CF_SQL_VARCHAR" />)
</cfquery>
1 голос
/ 10 июня 2019

Можете ли вы объяснить это немного дальше? Почему вы разрешаете отправлять форму с измененными данными, если вы не можете обновить саму запись? Если вы нажмете Save, сравните данные формы с данными запроса, и действие вызовет функцию Create, если данные отличаются.

Допустим, у вас есть запрос и форма вещи:

<cfquery name="myThing">
    SELECT 
        thing_id,
        thing_name,
        thing_foo
    FROM 
        things 
    where 
        thingID = <cfqueryparam value="#url.thingID#">
</cfquery>

<form> 
    <input type="hidden" name="thing_id" value="#myThing.thing_id#">
    <input type="text" name="thing_name" value="#myThing.thing_name#">
    <input type="text" name="thing_foo" value="#myThing.thing_foo#">
    <button type="submit">Submit</button>
</form>

Если вам нужно сравнить отправленные данные с данными, которые уже есть в базе данных, вы можете просто снова выполнить запрос на странице обработки формы и сравнить эти значения с представленными значениями формы. В этом примере предполагается, что вы назвали поля формы такими же, как столбцы таблицы базы данных.

<cfset delta = false>
<cfloop item="key" collection="#myThing#">
    <cfif structKeyExists(form, key)>
        <cfif form[key] NEQ myThing[key]>
            <cfset delta = true>
        </cfif>
    </cfif>
</cfloop>

Если какие-либо значения отличаются, создайте новую запись. Не представляю, что нужно делать, если отправленные значения не изменились.

<cfif delta>
    <!--- Create a new record. --->
<cfelse>
    <!--- ¯\_(ツ)_/¯ --->
</cfif>

Я также видел, что это сделано, когда исходные значения хранятся в скрытых полях формы и отправляются вместе с редактируемыми полями формы. Вы можете сделать это, но нет никакой гарантии, что значения в БД не изменились между тем, как вы рендерили форму и затем отправили ее.

У вас все еще будет проблема с тем, как определить, изменились ли значения БД на пути к БД, но я не уверен, нужна ли вам такая детальная проверка.

0 голосов
/ 12 июня 2019

Мы можем использовать cfquery для проверки таблицы с имеющимися данными или без нее. Если данные не совпадают, значит мы можем вставить форму. Следующий код может быть связан с вашим сценарием.

<cfif structKeyExists(form,"Submit")>
    <cfquery name="checkFormExisting" datasource="myDSN">
        SELECT * 
        FROM USERS 
        WHERE data1  = <cfqueryparam value="#form.data1# cfsqltype="cf_sql_varchar">
            OR data2 = <cfqueryparam value="#form.data2# cfsqltype="cf_sql_varchar">
            OR data3 = <cfqueryparam value="#form.data3# cfsqltype="cf_sql_varchar">
    </cfquery>

    <cfif checkFormExisting.recordCount EQ 0>
        INSERT INTO 
            USERS (
                data1,data2,data3
                ) 
                VALUES (
                    <cfqueryparam value="#form.data1# cfsqltype="cf_sql_varchar">,
                    <cfqueryparam value="#form.data2# cfsqltype="cf_sql_varchar">,
                    <cfqueryparam value="#form.data3# cfsqltype="cf_sql_varchar">
                )
    </cfif>
</cfif>

Надеюсь, вы спрашиваете, как приведенный выше код для вашего сценария.

...