<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fp2011</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Fp2011"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Fp2011"/>
	<updated>2026-09-13T18:02:31Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_web_service_and_a_web_service_function&amp;diff=30071</id>
		<title>Creating a web service and a web service function</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_web_service_and_a_web_service_function&amp;diff=30071"/>
		<updated>2011-10-22T17:57:53Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* Define the web service description */  associative arrays vs objects, null values&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
= Simple example =&lt;br /&gt;
Have a look to the [https://github.com/moodlehq/moodle-local_wstemplate web service template]. It is a simple hello_world function.&lt;br /&gt;
&lt;br /&gt;
= Complex example=&lt;br /&gt;
We will write a web service function &#039;&#039;create_groups($groups)&#039;&#039;. This function create a group into a Moodle course. - actually the function already exists into Moodle. You can browse [https://github.com/moodle/moodle/blob/master/group/externallib.php Github repository] to have a look to the latest code. &lt;br /&gt;
&lt;br /&gt;
== Write the function specification documentation ==&lt;br /&gt;
&lt;br /&gt;
=== functional ===&lt;br /&gt;
&#039;&#039;create_groups($groups)&#039;&#039; will take a list of group object as parameters and it will return the same groups with their newly created id. If ever one group creation fails, the function will throw an exception, and no creation will happen. &lt;br /&gt;
&lt;br /&gt;
=== technical ===&lt;br /&gt;
* &#039;&#039;&#039;the core functions&#039;&#039;&#039;: for our case we will use &#039;&#039;groups_create_group()&#039;&#039; from [http://cvs.moodle.org/moodle/group/ /group/lib.php]. Of course not every core function exists and in some other cases you could have to write them.  &lt;br /&gt;
* &#039;&#039;&#039;the parameter types&#039;&#039;&#039;: for our case we&#039;ll send a list of object. This object are groups, with id/name/courseid.&lt;br /&gt;
* &#039;&#039;&#039;the returned value types&#039;&#039;&#039;: for our case we want to send back a list of group object with their id.&lt;br /&gt;
* &#039;&#039;&#039;the user capabilities&#039;&#039;&#039;: for our case the user will need the &#039;&#039;moodle/course:managegroups&#039;&#039; capability.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Write a simple test client ==&lt;br /&gt;
&lt;br /&gt;
Help yourself with [the demo clients https://github.com/moodlehq/sample-ws-clients]. It is essential to start to write the web service test client before the actual function. You could discover use cases that you didn&#039;t think of when writing the specifications. See also [[Creating_a_web_service_client]]&lt;br /&gt;
&lt;br /&gt;
== Declare the web service function ==&lt;br /&gt;
Web service functions are declared into &#039;&#039;db/services.php&#039;&#039; of each component. In our case &#039;&#039;create_groups()&#039;&#039; is a core external function, so we will add the function to [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$functions = array(&lt;br /&gt;
    &#039;moodle_group_create_groups&#039; =&amp;gt; array(         //web service function name&lt;br /&gt;
        &#039;classname&#039;   =&amp;gt; &#039;moodle_group_external&#039;,  //class containing the external function&lt;br /&gt;
        &#039;methodname&#039;  =&amp;gt; &#039;create_groups&#039;,          //external function name&lt;br /&gt;
        &#039;classpath&#039;   =&amp;gt; &#039;group/externallib.php&#039;,  //file containing the class/external function&lt;br /&gt;
        &#039;description&#039; =&amp;gt; &#039;Creates new groups.&#039;,    //human readable description of the web service function&lt;br /&gt;
        &#039;type&#039;        =&amp;gt; &#039;write&#039;,                  //database rights of the web service function (read, write)&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here you should ask yourself what is the difference between a web service function and an external function. Web service function could be considered as a redirection to the external function. The web service function name is the name that is served by web service server to the client. By this way the client doesn&#039;t know about the external functions.&lt;br /&gt;
&lt;br /&gt;
The web service function name is arbitrary, but it must be globally unique so we highly recommend using the component name as prefix (and &amp;quot;moodle&amp;quot; for core functions).&lt;br /&gt;
&lt;br /&gt;
== Define the web service description ==&lt;br /&gt;
Some web service protocol need a full description of the web service function parameters and return value. For example we need to generate a full WSDL for SOAP if we expect a JAVA/.Net client to call our function. This WSDL need a complete and fully detailed description of the parameters.&amp;lt;br/&amp;gt;&lt;br /&gt;
Moreover we implemented a web service parameters validation process that also requires a full description of these parameters.&amp;lt;br/&amp;gt;&lt;br /&gt;
In conclusion, you must write these descriptions. They are not applied to the web service function but the external function, remember that the web service function is just a kind of redirection.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Descriptions are usually located in a class inside a file named &#039;&#039;externallib.php&#039;&#039; in the component folder. You probably remember that we referenced this &#039;&#039;moodle_group_external&#039;&#039; class into [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php]. Let&#039;s take a minute to talk about the [http://cvs.moodle.org/moodle/group/ /group/externallib.php] that we need to create.&lt;br /&gt;
&lt;br /&gt;
This file will contain all external functions. They are all related to each other. In our case the externallib.php file will contain all &#039;&#039;group&#039;&#039; related functions. For each external function, we will have:&lt;br /&gt;
* the external function, calling a core function.&lt;br /&gt;
* a function describing the parameters of the external function&lt;br /&gt;
* a function describing the return values of the external function&lt;br /&gt;
&lt;br /&gt;
Now we&#039;ll have look to the description of the &#039;&#039;create_group($groups)&#039;&#039; parameters. All parameter descriptions are included in a function called &#039;&#039;externalfunctionname_parameters()&#039;&#039;. In our case it will be &#039;&#039;create_groups_parameters()&#039;&#039; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once(&amp;quot;$CFG-&amp;gt;libdir/externallib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
class moodle_group_external extends external_api {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns description of method parameters&lt;br /&gt;
     * @return external_function_parameters&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups_parameters() {&lt;br /&gt;
        return new external_function_parameters(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok you are probably already here :) We have to understand this function very well. There are different approaches to understand this function, here is my personal one.&amp;lt;br/&amp;gt;&lt;br /&gt;
The function &#039;&#039;xxx_parameters()&#039;&#039; always returns an &#039;&#039;external_function_parameters&#039;&#039; object. This object is initialized with an associative array. This array contains the parameter descriptions. If the external function has no parameters, this array will be empty (but present). If the external function has three parameters, it will have three elements, the keys being the parameters names.&lt;br /&gt;
Each of its element is a parameter description. A parameter can be a list (external_multiple_structure), an object (external_single_structure) or a primary type (external_value).&lt;br /&gt;
&lt;br /&gt;
Our create_groups() function expects one parameter named &#039;&#039;groups&#039;&#039;, so we will first write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns description of method parameters&lt;br /&gt;
     * @return external_function_parameters&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups_parameters() {&lt;br /&gt;
        return new external_function_parameters(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;groups&#039; =&amp;gt; ...&lt;br /&gt;
                &lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This &#039;&#039;groups&#039;&#039; parameter is a list of group. So we will write :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    ...&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An external_multiple_structure object (list) can be initialized with external_single_structure (object), external_value (primary type) or another external_multiple_structure (list). You will respectively obtain a list of a unique object type, a list of a unique primary type, or a list of a list. These last case being probably bad design.&amp;lt;br/&amp;gt;&lt;br /&gt;
In our case we want a list of group, a group being a object. Have a look on how would describe a group :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;             &lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; ...,&lt;br /&gt;
                        )&lt;br /&gt;
                    )           &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From this code you can guess that an external_single_structure is initialized with an associative array containing the object attibutes.&amp;lt;br/&amp;gt; &lt;br /&gt;
Thus a list of group will be defined :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; ...,&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each group attribute is a primary type. &#039;&#039;courseid&#039;&#039; is an integer. &#039;&#039;name&#039;&#039; is a string, &#039;&#039;description&#039;&#039; is a string, and &#039;&#039;enrolmentkey&#039;&#039; is also a string. To define a primary type we use the &#039;&#039;external_value&#039;&#039; object. This &#039;&#039;external_value&#039;&#039; is initialized with a non associative array containing three elements:&lt;br /&gt;
# the primary type&lt;br /&gt;
# a human readable description&lt;br /&gt;
# is the parameter optional (if the parameter is mandatory we don&#039;t need this third element)&lt;br /&gt;
&lt;br /&gt;
For example for the &#039;&#039;courseid&#039;&#039; and &#039;&#039;name&#039;&#039; attribut we would define:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;                 &lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),                         &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So our list of object description will be :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you should be able to understand this parameter description function. You also should be able to deduce how to write the return value description function. &lt;br /&gt;
&lt;br /&gt;
Return value function always returns one primary or complex value, so we don&#039;t need to return external_function_parameters object. In our case we want to return the exact same list of groups. The only change being that we want the group to have an id attribute. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
public static function create_groups_returns() {&lt;br /&gt;
        return new external_multiple_structure(&lt;br /&gt;
            new external_single_structure(&lt;br /&gt;
                array(&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; new external_value(PARAM_INT, &#039;group record id&#039;),&lt;br /&gt;
                    &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                    &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                    &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                    &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that &#039;&#039;external_single_structure&#039;&#039; describes an associative array. If your function returns an object, you must first convert it to an array.&lt;br /&gt;
&lt;br /&gt;
The returned value cannot be null, and if it is an array, none of its values can be null. If your function returns for example a list of database records with $DB-&amp;gt;get_records(), you must check each field of each row to replace null values, and convert each row to an associative array.&lt;br /&gt;
&lt;br /&gt;
Here ends the most difficult part of the web service infrastructure implementation. Congratulation!&lt;br /&gt;
&lt;br /&gt;
=== Mandatory, Optional or Default ===&lt;br /&gt;
An attribute can be defined MANDATORY, OPTIONAL, or DEFAULT. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;                 &lt;br /&gt;
                            &#039;yearofstudy&#039; =&amp;gt; new external_value(PARAM_INT, &#039;year of study&#039;,VALUE_DEFAULT, 1979),                        &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter VALUE_DEFAULT indicates that &#039;yearofstudy&#039; is set to a default value if the attribute is not supply. When you set VALUE_DEFAULT in the description, you must also write a default value as fourth parameter. Here the default value of &#039;yearofstudy&#039; is 1979.&lt;br /&gt;
&lt;br /&gt;
The three values can be understood like this :&lt;br /&gt;
* VALUE_REQUIRED - if the parameter is not supplied, then the server throws an exception&lt;br /&gt;
* VALUE_OPTIONAL - if the parameter is not supplied, then the param has no value&lt;br /&gt;
* VALUE_DEFAULT - if the parameter is not supplied, then the default value is used&lt;br /&gt;
&lt;br /&gt;
== Define the external function ==&lt;br /&gt;
We declared our web service function and we defined the external function parameters and return values. We will now implement the external function. Let&#039;s have a full look to the external function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Create groups&lt;br /&gt;
     * @param array $groups array of group description arrays (with keys groupname and courseid)&lt;br /&gt;
     * @return array of newly created groups&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups($groups) { //Don&#039;t forget to set it as static&lt;br /&gt;
        global $CFG, $DB;&lt;br /&gt;
        require_once(&amp;quot;$CFG-&amp;gt;dirroot/group/lib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        $params = self::validate_parameters(self::create_groups_parameters(), array(&#039;groups&#039;=&amp;gt;$groups));&lt;br /&gt;
&lt;br /&gt;
        $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&lt;br /&gt;
        $groups = array();&lt;br /&gt;
&lt;br /&gt;
        foreach ($params[&#039;groups&#039;] as $group) {&lt;br /&gt;
            $group = (object)$group;&lt;br /&gt;
&lt;br /&gt;
            if (trim($group-&amp;gt;name) == &#039;&#039;) {&lt;br /&gt;
                throw new invalid_parameter_exception(&#039;Invalid group name&#039;);&lt;br /&gt;
            }&lt;br /&gt;
            if ($DB-&amp;gt;get_record(&#039;groups&#039;, array(&#039;courseid&#039;=&amp;gt;$group-&amp;gt;courseid, &#039;name&#039;=&amp;gt;$group-&amp;gt;name))) {&lt;br /&gt;
                throw new invalid_parameter_exception(&#039;Group with the same name already exists in the course&#039;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now security checks&lt;br /&gt;
            $context = get_context_instance(CONTEXT_COURSE, $group-&amp;gt;courseid);&lt;br /&gt;
            self::validate_context($context);&lt;br /&gt;
            require_capability(&#039;moodle/course:managegroups&#039;, $context);&lt;br /&gt;
&lt;br /&gt;
            // finally create the group&lt;br /&gt;
            $group-&amp;gt;id = groups_create_group($group, false);&lt;br /&gt;
            $groups[] = (array)$group;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $transaction-&amp;gt;allow_commit();&lt;br /&gt;
&lt;br /&gt;
        return $groups;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First let&#039;s have a look at &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $params = self::validate_parameters(self::create_groups_parameters(), array(&#039;groups&#039;=&amp;gt;$groups));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This &#039;&#039;validate_parameters&#039;&#039; function validates the external function parameters against the description. It will return an exception if some required parameters are missing, if parameters are not well-formed, and check the parameters validity. The array(&#039;groups&#039;=&amp;gt;$groups) take the expected parameters by the description function. &lt;br /&gt;
&lt;br /&gt;
A very important point: the parameters of your external function (&#039;&#039;$groups&#039;&#039; into &#039;&#039;public static function create_groups(&#039;&#039;&#039;$groups&#039;&#039;&#039;) {&#039;&#039;) should be in the exact same order as the ones into your description function (&#039;&#039;&#039;return new external_function_parameters( array( &#039;&#039;&#039;&#039;groups&#039;&#039;&#039;&#039; =&amp;gt; ... )&#039;&#039;&#039;). I agree that our example function doesn&#039;t give us a good example :)&lt;br /&gt;
&lt;br /&gt;
Then we have the following line&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Our function has for goal to create multiple group. The function is calling multiple time the &#039;&#039;&#039;groups_create_group()&#039;&#039;&#039; core function. If ever one function fail and return an exception, we do not want to commit any change. It&#039;s why we declare this line that suspend any commit till we write the following line&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will also notice that our function throws exception. It is automatically handle by Moodle web service servers.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
throw new invalid_parameter_exception(&#039;Group with the same name already exists in the course&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And yet again another important point: the context checking and capability checking happens into the external function. In a long term, in Moodle 2.0, all context/capability checks will disappear from the core functions and will be located into the external functions&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// now security checks&lt;br /&gt;
$context = get_context_instance(CONTEXT_COURSE, $group-&amp;gt;courseid);&lt;br /&gt;
self::validate_context($context);&lt;br /&gt;
require_capability(&#039;moodle/course:managegroups&#039;, $context);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Last point, the return values will be parsed by the Moodle web service servers. Only the required values describe into the function description will be returned. An error will be returned if the external function doesn&#039;t return some required values.&lt;br /&gt;
&lt;br /&gt;
== Add the web service function into a service ==&lt;br /&gt;
In some specific case we could want to set a service by default, so the Moodle administrator doesn&#039;t need to set a new one. We can do that by writing the following code into [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $services = array(&lt;br /&gt;
      &#039;groupservice&#039; =&amp;gt; array(                                                //the name of the web service&lt;br /&gt;
          &#039;functions&#039; =&amp;gt; array (&#039;moodle_add_groups&#039;, &#039;moodle_create_groups&#039;), //web service functions of this service&lt;br /&gt;
          &#039;requiredcapability&#039; =&amp;gt; &#039;some/capability:specified&#039;,                //if set, the web service user need this capability to access &lt;br /&gt;
                                                                              //any function of this service                   &lt;br /&gt;
          &#039;restrictedusers&#039; = &amp;gt;1,                                             //if enabled, the Moodle administrator must link some user to this service&lt;br /&gt;
                                                                              //into the administration&lt;br /&gt;
          &#039;enabled&#039;=&amp;gt;0,                                                       //if enabled, the service can be reachable on a default installation&lt;br /&gt;
       )&lt;br /&gt;
  );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code we created a service called &#039;&#039;groupservice&#039;&#039;. This service contains two functions &#039;&#039;moodle_add_groups&#039;&#039;/&#039;&#039;moodle_create_groups&#039;&#039;. &amp;lt;br/&amp;gt;&lt;br /&gt;
This possibility to preset a service exists to facilitate the administrator life. He can easily enable a bunch of function. &amp;lt;br/&amp;gt;&lt;br /&gt;
However it is not possible for an administrator to add/remove any function from preset service. For security purpose, it is not a recommended to preset a service.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Web services]]&lt;br /&gt;
* [[External services security]]&lt;br /&gt;
* [[External services description]]&lt;br /&gt;
* [[Creating_a_web_service_client]]&lt;br /&gt;
* [https://docs.moodle.org/en/Web_Services Web services]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=169078 Using Webservices with Zend Rest Client]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Services]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_web_service_and_a_web_service_function&amp;diff=30070</id>
		<title>Creating a web service and a web service function</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_web_service_and_a_web_service_function&amp;diff=30070"/>
		<updated>2011-10-22T11:41:20Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* Define the web service description */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
= Simple example =&lt;br /&gt;
Have a look to the [https://github.com/moodlehq/moodle-local_wstemplate web service template]. It is a simple hello_world function.&lt;br /&gt;
&lt;br /&gt;
= Complex example=&lt;br /&gt;
We will write a web service function &#039;&#039;create_groups($groups)&#039;&#039;. This function create a group into a Moodle course. - actually the function already exists into Moodle. You can browse [https://github.com/moodle/moodle/blob/master/group/externallib.php Github repository] to have a look to the latest code. &lt;br /&gt;
&lt;br /&gt;
== Write the function specification documentation ==&lt;br /&gt;
&lt;br /&gt;
=== functional ===&lt;br /&gt;
&#039;&#039;create_groups($groups)&#039;&#039; will take a list of group object as parameters and it will return the same groups with their newly created id. If ever one group creation fails, the function will throw an exception, and no creation will happen. &lt;br /&gt;
&lt;br /&gt;
=== technical ===&lt;br /&gt;
* &#039;&#039;&#039;the core functions&#039;&#039;&#039;: for our case we will use &#039;&#039;groups_create_group()&#039;&#039; from [http://cvs.moodle.org/moodle/group/ /group/lib.php]. Of course not every core function exists and in some other cases you could have to write them.  &lt;br /&gt;
* &#039;&#039;&#039;the parameter types&#039;&#039;&#039;: for our case we&#039;ll send a list of object. This object are groups, with id/name/courseid.&lt;br /&gt;
* &#039;&#039;&#039;the returned value types&#039;&#039;&#039;: for our case we want to send back a list of group object with their id.&lt;br /&gt;
* &#039;&#039;&#039;the user capabilities&#039;&#039;&#039;: for our case the user will need the &#039;&#039;moodle/course:managegroups&#039;&#039; capability.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Write a simple test client ==&lt;br /&gt;
&lt;br /&gt;
Help yourself with [the demo clients https://github.com/moodlehq/sample-ws-clients]. It is essential to start to write the web service test client before the actual function. You could discover use cases that you didn&#039;t think of when writing the specifications. See also [[Creating_a_web_service_client]]&lt;br /&gt;
&lt;br /&gt;
== Declare the web service function ==&lt;br /&gt;
Web service functions are declared into &#039;&#039;db/services.php&#039;&#039; of each component. In our case &#039;&#039;create_groups()&#039;&#039; is a core external function, so we will add the function to [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$functions = array(&lt;br /&gt;
    &#039;moodle_group_create_groups&#039; =&amp;gt; array(         //web service function name&lt;br /&gt;
        &#039;classname&#039;   =&amp;gt; &#039;moodle_group_external&#039;,  //class containing the external function&lt;br /&gt;
        &#039;methodname&#039;  =&amp;gt; &#039;create_groups&#039;,          //external function name&lt;br /&gt;
        &#039;classpath&#039;   =&amp;gt; &#039;group/externallib.php&#039;,  //file containing the class/external function&lt;br /&gt;
        &#039;description&#039; =&amp;gt; &#039;Creates new groups.&#039;,    //human readable description of the web service function&lt;br /&gt;
        &#039;type&#039;        =&amp;gt; &#039;write&#039;,                  //database rights of the web service function (read, write)&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here you should ask yourself what is the difference between a web service function and an external function. Web service function could be considered as a redirection to the external function. The web service function name is the name that is served by web service server to the client. By this way the client doesn&#039;t know about the external functions.&lt;br /&gt;
&lt;br /&gt;
The web service function name is arbitrary, but it must be globally unique so we highly recommend using the component name as prefix (and &amp;quot;moodle&amp;quot; for core functions).&lt;br /&gt;
&lt;br /&gt;
== Define the web service description ==&lt;br /&gt;
Some web service protocol need a full description of the web service function parameters and return value. For example we need to generate a full WSDL for SOAP if we expect a JAVA/.Net client to call our function. This WSDL need a complete and fully detailed description of the parameters.&amp;lt;br/&amp;gt;&lt;br /&gt;
Moreover we implemented a web service parameters validation process that also requires a full description of these parameters.&amp;lt;br/&amp;gt;&lt;br /&gt;
In conclusion, you must write these descriptions. They are not applied to the web service function but the external function, remember that the web service function is just a kind of redirection.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Descriptions are usually located in a class inside a file named &#039;&#039;externallib.php&#039;&#039; in the component folder. You probably remember that we referenced this &#039;&#039;moodle_group_external&#039;&#039; class into [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php]. Let&#039;s take a minute to talk about the [http://cvs.moodle.org/moodle/group/ /group/externallib.php] that we need to create.&lt;br /&gt;
&lt;br /&gt;
This file will contain all external functions. They are all related to each other. In our case the externallib.php file will contain all &#039;&#039;group&#039;&#039; related functions. For each external function, we will have:&lt;br /&gt;
* the external function, calling a core function.&lt;br /&gt;
* a function describing the parameters of the external function&lt;br /&gt;
* a function describing the return values of the external function&lt;br /&gt;
&lt;br /&gt;
Now we&#039;ll have look to the description of the &#039;&#039;create_group($groups)&#039;&#039; parameters. All parameter descriptions are included in a function called &#039;&#039;externalfunctionname_parameters()&#039;&#039;. In our case it will be &#039;&#039;create_groups_parameters()&#039;&#039; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once(&amp;quot;$CFG-&amp;gt;libdir/externallib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
class moodle_group_external extends external_api {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns description of method parameters&lt;br /&gt;
     * @return external_function_parameters&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups_parameters() {&lt;br /&gt;
        return new external_function_parameters(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok you are probably already here :) We have to understand this function very well. There are different approaches to understand this function, here is my personal one.&amp;lt;br/&amp;gt;&lt;br /&gt;
The function &#039;&#039;xxx_parameters()&#039;&#039; always returns an &#039;&#039;external_function_parameters&#039;&#039; object. This object is initialized with an associative array. This array contains the parameter descriptions. If the external function has no parameters, this array will be empty (but present). If the external function has three parameters, it will have three elements, the keys being the parameters names.&lt;br /&gt;
Each of its element is a parameter description. A parameter can be a list (external_multiple_structure), an object (external_single_structure) or a primary type (external_value).&lt;br /&gt;
&lt;br /&gt;
Our create_groups() function expects one parameter named &#039;&#039;groups&#039;&#039;, so we will first write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns description of method parameters&lt;br /&gt;
     * @return external_function_parameters&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups_parameters() {&lt;br /&gt;
        return new external_function_parameters(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;groups&#039; =&amp;gt; ...&lt;br /&gt;
                &lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This &#039;&#039;groups&#039;&#039; parameter is a list of group. So we will write :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    ...&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An external_multiple_structure object (list) can be initialized with external_single_structure (object), external_value (primary type) or another external_multiple_structure (list). You will respectively obtain a list of a unique object type, a list of a unique primary type, or a list of a list. These last case being probably bad design.&amp;lt;br/&amp;gt;&lt;br /&gt;
In our case we want a list of group, a group being a object. Have a look on how would describe a group :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;             &lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; ...,&lt;br /&gt;
                        )&lt;br /&gt;
                    )           &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From this code you can guess that an external_single_structure is initialized with an associative array containing the object attibutes.&amp;lt;br/&amp;gt; &lt;br /&gt;
Thus a list of group will be defined :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; ...,&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each group attribute is a primary type. &#039;&#039;courseid&#039;&#039; is an integer. &#039;&#039;name&#039;&#039; is a string, &#039;&#039;description&#039;&#039; is a string, and &#039;&#039;enrolmentkey&#039;&#039; is also a string. To define a primary type we use the &#039;&#039;external_value&#039;&#039; object. This &#039;&#039;external_value&#039;&#039; is initialized with a non associative array containing three elements:&lt;br /&gt;
# the primary type&lt;br /&gt;
# a human readable description&lt;br /&gt;
# is the parameter optional (if the parameter is mandatory we don&#039;t need this third element)&lt;br /&gt;
&lt;br /&gt;
For example for the &#039;&#039;courseid&#039;&#039; and &#039;&#039;name&#039;&#039; attribut we would define:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;                 &lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),                         &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So our list of object description will be :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you should be able to understand this parameter description function. You also should be able to deduce how to write the return value description function. &lt;br /&gt;
&lt;br /&gt;
Return value function always returns one primary or complex value, so we don&#039;t need to return external_function_parameters object. In our case we want to return the exact same list of groups. The only change being that we want the group to have an id attribute. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
public static function create_groups_returns() {&lt;br /&gt;
        return new external_multiple_structure(&lt;br /&gt;
            new external_single_structure(&lt;br /&gt;
                array(&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; new external_value(PARAM_INT, &#039;group record id&#039;),&lt;br /&gt;
                    &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                    &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                    &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                    &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here ends the most difficult part of the web service infrastructure implementation. Congratulation!&lt;br /&gt;
&lt;br /&gt;
=== Mandatory, Optional or Default ===&lt;br /&gt;
An attribute can be defined MANDATORY, OPTIONAL, or DEFAULT. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;                 &lt;br /&gt;
                            &#039;yearofstudy&#039; =&amp;gt; new external_value(PARAM_INT, &#039;year of study&#039;,VALUE_DEFAULT, 1979),                        &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter VALUE_DEFAULT indicates that &#039;yearofstudy&#039; is set to a default value if the attribute is not supply. When you set VALUE_DEFAULT in the description, you must also write a default value as fourth parameter. Here the default value of &#039;yearofstudy&#039; is 1979.&lt;br /&gt;
&lt;br /&gt;
The three values can be understood like this :&lt;br /&gt;
* VALUE_REQUIRED - if the parameter is not supplied, then the server throws an exception&lt;br /&gt;
* VALUE_OPTIONAL - if the parameter is not supplied, then the param has no value&lt;br /&gt;
* VALUE_DEFAULT - if the parameter is not supplied, then the default value is used&lt;br /&gt;
&lt;br /&gt;
== Define the external function ==&lt;br /&gt;
We declared our web service function and we defined the external function parameters and return values. We will now implement the external function. Let&#039;s have a full look to the external function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Create groups&lt;br /&gt;
     * @param array $groups array of group description arrays (with keys groupname and courseid)&lt;br /&gt;
     * @return array of newly created groups&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups($groups) { //Don&#039;t forget to set it as static&lt;br /&gt;
        global $CFG, $DB;&lt;br /&gt;
        require_once(&amp;quot;$CFG-&amp;gt;dirroot/group/lib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        $params = self::validate_parameters(self::create_groups_parameters(), array(&#039;groups&#039;=&amp;gt;$groups));&lt;br /&gt;
&lt;br /&gt;
        $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&lt;br /&gt;
        $groups = array();&lt;br /&gt;
&lt;br /&gt;
        foreach ($params[&#039;groups&#039;] as $group) {&lt;br /&gt;
            $group = (object)$group;&lt;br /&gt;
&lt;br /&gt;
            if (trim($group-&amp;gt;name) == &#039;&#039;) {&lt;br /&gt;
                throw new invalid_parameter_exception(&#039;Invalid group name&#039;);&lt;br /&gt;
            }&lt;br /&gt;
            if ($DB-&amp;gt;get_record(&#039;groups&#039;, array(&#039;courseid&#039;=&amp;gt;$group-&amp;gt;courseid, &#039;name&#039;=&amp;gt;$group-&amp;gt;name))) {&lt;br /&gt;
                throw new invalid_parameter_exception(&#039;Group with the same name already exists in the course&#039;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now security checks&lt;br /&gt;
            $context = get_context_instance(CONTEXT_COURSE, $group-&amp;gt;courseid);&lt;br /&gt;
            self::validate_context($context);&lt;br /&gt;
            require_capability(&#039;moodle/course:managegroups&#039;, $context);&lt;br /&gt;
&lt;br /&gt;
            // finally create the group&lt;br /&gt;
            $group-&amp;gt;id = groups_create_group($group, false);&lt;br /&gt;
            $groups[] = (array)$group;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $transaction-&amp;gt;allow_commit();&lt;br /&gt;
&lt;br /&gt;
        return $groups;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First let&#039;s have a look at &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $params = self::validate_parameters(self::create_groups_parameters(), array(&#039;groups&#039;=&amp;gt;$groups));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This &#039;&#039;validate_parameters&#039;&#039; function validates the external function parameters against the description. It will return an exception if some required parameters are missing, if parameters are not well-formed, and check the parameters validity. The array(&#039;groups&#039;=&amp;gt;$groups) take the expected parameters by the description function. &lt;br /&gt;
&lt;br /&gt;
A very important point: the parameters of your external function (&#039;&#039;$groups&#039;&#039; into &#039;&#039;public static function create_groups(&#039;&#039;&#039;$groups&#039;&#039;&#039;) {&#039;&#039;) should be in the exact same order as the ones into your description function (&#039;&#039;&#039;return new external_function_parameters( array( &#039;&#039;&#039;&#039;groups&#039;&#039;&#039;&#039; =&amp;gt; ... )&#039;&#039;&#039;). I agree that our example function doesn&#039;t give us a good example :)&lt;br /&gt;
&lt;br /&gt;
Then we have the following line&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Our function has for goal to create multiple group. The function is calling multiple time the &#039;&#039;&#039;groups_create_group()&#039;&#039;&#039; core function. If ever one function fail and return an exception, we do not want to commit any change. It&#039;s why we declare this line that suspend any commit till we write the following line&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will also notice that our function throws exception. It is automatically handle by Moodle web service servers.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
throw new invalid_parameter_exception(&#039;Group with the same name already exists in the course&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And yet again another important point: the context checking and capability checking happens into the external function. In a long term, in Moodle 2.0, all context/capability checks will disappear from the core functions and will be located into the external functions&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// now security checks&lt;br /&gt;
$context = get_context_instance(CONTEXT_COURSE, $group-&amp;gt;courseid);&lt;br /&gt;
self::validate_context($context);&lt;br /&gt;
require_capability(&#039;moodle/course:managegroups&#039;, $context);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Last point, the return values will be parsed by the Moodle web service servers. Only the required values describe into the function description will be returned. An error will be returned if the external function doesn&#039;t return some required values.&lt;br /&gt;
&lt;br /&gt;
== Add the web service function into a service ==&lt;br /&gt;
In some specific case we could want to set a service by default, so the Moodle administrator doesn&#039;t need to set a new one. We can do that by writing the following code into [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $services = array(&lt;br /&gt;
      &#039;groupservice&#039; =&amp;gt; array(                                                //the name of the web service&lt;br /&gt;
          &#039;functions&#039; =&amp;gt; array (&#039;moodle_add_groups&#039;, &#039;moodle_create_groups&#039;), //web service functions of this service&lt;br /&gt;
          &#039;requiredcapability&#039; =&amp;gt; &#039;some/capability:specified&#039;,                //if set, the web service user need this capability to access &lt;br /&gt;
                                                                              //any function of this service                   &lt;br /&gt;
          &#039;restrictedusers&#039; = &amp;gt;1,                                             //if enabled, the Moodle administrator must link some user to this service&lt;br /&gt;
                                                                              //into the administration&lt;br /&gt;
          &#039;enabled&#039;=&amp;gt;0,                                                       //if enabled, the service can be reachable on a default installation&lt;br /&gt;
       )&lt;br /&gt;
  );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code we created a service called &#039;&#039;groupservice&#039;&#039;. This service contains two functions &#039;&#039;moodle_add_groups&#039;&#039;/&#039;&#039;moodle_create_groups&#039;&#039;. &amp;lt;br/&amp;gt;&lt;br /&gt;
This possibility to preset a service exists to facilitate the administrator life. He can easily enable a bunch of function. &amp;lt;br/&amp;gt;&lt;br /&gt;
However it is not possible for an administrator to add/remove any function from preset service. For security purpose, it is not a recommended to preset a service.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Web services]]&lt;br /&gt;
* [[External services security]]&lt;br /&gt;
* [[External services description]]&lt;br /&gt;
* [[Creating_a_web_service_client]]&lt;br /&gt;
* [https://docs.moodle.org/en/Web_Services Web services]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=169078 Using Webservices with Zend Rest Client]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Services]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Creating_a_web_service_and_a_web_service_function&amp;diff=30019</id>
		<title>Creating a web service and a web service function</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Creating_a_web_service_and_a_web_service_function&amp;diff=30019"/>
		<updated>2011-10-13T21:40:24Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}&lt;br /&gt;
&lt;br /&gt;
= Simple example =&lt;br /&gt;
Have a look to the [https://github.com/moodlehq/moodle-local_wstemplate web service template]. It is a simple hello_world function.&lt;br /&gt;
&lt;br /&gt;
= Complex example=&lt;br /&gt;
We will write a web service function &#039;&#039;create_groups($groups)&#039;&#039;. This function create a group into a Moodle course. - actually the function already exists into Moodle. You can browse [https://github.com/moodle/moodle/blob/master/group/externallib.php Github repository] to have a look to the latest code. &lt;br /&gt;
&lt;br /&gt;
== Write the function specification documentation ==&lt;br /&gt;
&lt;br /&gt;
=== functional ===&lt;br /&gt;
&#039;&#039;create_groups($groups)&#039;&#039; will take a list of group object as parameters and it will return the same groups with their newly created id. If ever one group creation fails, the function will throw an exception, and no creation will happen. &lt;br /&gt;
&lt;br /&gt;
=== technical ===&lt;br /&gt;
* &#039;&#039;&#039;the core functions&#039;&#039;&#039;: for our case we will use &#039;&#039;groups_create_group()&#039;&#039; from [http://cvs.moodle.org/moodle/group/ /group/lib.php]. Of course not every core function exists and in some other cases you could have to write them.  &lt;br /&gt;
* &#039;&#039;&#039;the parameter types&#039;&#039;&#039;: for our case we&#039;ll send a list of object. This object are groups, with id/name/courseid.&lt;br /&gt;
* &#039;&#039;&#039;the returned value types&#039;&#039;&#039;: for our case we want to send back a list of group object with their id.&lt;br /&gt;
* &#039;&#039;&#039;the user capabilities&#039;&#039;&#039;: for our case the user will need the &#039;&#039;moodle/course:managegroups&#039;&#039; capability.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Write a simple test client ==&lt;br /&gt;
&lt;br /&gt;
Help yourself with [the demo clients https://github.com/moodlehq/sample-ws-clients]. It is essential to start to write the web service test client before the actual function. You could discover use cases that you didn&#039;t think of when writing the specifications. See also [[Creating_a_web_service_client]]&lt;br /&gt;
&lt;br /&gt;
== Declare the web service function ==&lt;br /&gt;
Web service functions are declared into &#039;&#039;db/services.php&#039;&#039; of each component. In our case &#039;&#039;create_groups()&#039;&#039; is a core external function, so we will add the function to [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$functions = array(&lt;br /&gt;
    &#039;moodle_group_create_groups&#039; =&amp;gt; array(         //web service function name&lt;br /&gt;
        &#039;classname&#039;   =&amp;gt; &#039;moodle_group_external&#039;,  //class containing the external function&lt;br /&gt;
        &#039;methodname&#039;  =&amp;gt; &#039;create_groups&#039;,          //external function name&lt;br /&gt;
        &#039;classpath&#039;   =&amp;gt; &#039;group/externallib.php&#039;,  //file containing the class/external function&lt;br /&gt;
        &#039;description&#039; =&amp;gt; &#039;Creates new groups.&#039;,    //human readable description of the web service function&lt;br /&gt;
        &#039;type&#039;        =&amp;gt; &#039;write&#039;,                  //database rights of the web service function (read, write)&lt;br /&gt;
    ),&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here you should ask yourself what is the difference between a web service function and an external function. Web service function could be considered as a redirection to the external function. The web service function name is the name that is served by web service server to the client. By this way the client doesn&#039;t know about the external functions.&lt;br /&gt;
&lt;br /&gt;
The web service function name is arbitrary, but it must be globally unique so we highly recommend using the component name as prefix (and &amp;quot;moodle&amp;quot; for core functions).&lt;br /&gt;
&lt;br /&gt;
== Define the web service description ==&lt;br /&gt;
Some web service protocol need a full description of the web service function parameters and return value. For example we need to generate a full WSDL for SOAP if we expect a JAVA/.Net client to call our function. This WSDL need a complete and fully detailed description of the parameters.&amp;lt;br/&amp;gt;&lt;br /&gt;
Moreover we implemented a web service parameters validation process that also require a full description of these parameters.&amp;lt;br/&amp;gt;&lt;br /&gt;
In conclusion, you must write these descriptions. These descriptions are not applied on the web service function but the external function, remember that the web service function is just a kind of redirection.&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Descriptions are usually located into a class into an externallib.php in the component folder. You probably remember that we referenced this &#039;&#039;moodle_group_external&#039;&#039; class into [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php]. Let&#039;s take a minuteto talk about the [http://cvs.moodle.org/moodle/group/ /group/externallib.php] that we need to create.&lt;br /&gt;
&lt;br /&gt;
This file will contain all external functions. These functions are all related together. In our case the externallib.php file will contain all &#039;&#039;group&#039;&#039; related functions. For each external function, we will have:&lt;br /&gt;
* the external function, calling a core function.&lt;br /&gt;
* a function describing the parameters of the external function&lt;br /&gt;
* a function describing the return values of the external function&lt;br /&gt;
&lt;br /&gt;
Now we&#039;ll have look to the description of the &#039;&#039;create_group($groups)&#039;&#039; parameters. All parameter descriptions are included into a function called &#039;&#039;externalfunctionname_parameters()&#039;&#039;. In our case it will be &#039;&#039;create_groups_parameters()&#039;&#039; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
require_once(&amp;quot;$CFG-&amp;gt;libdir/externallib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
class moodle_group_external extends external_api {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns description of method parameters&lt;br /&gt;
     * @return external_function_parameters&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups_parameters() {&lt;br /&gt;
        return new external_function_parameters(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ok you are probably already here :) We have to understand this function very well. There is different approaches to understand this function, here is my personal one.&amp;lt;br/&amp;gt;&lt;br /&gt;
The function &#039;&#039;xxx_parameters()&#039;&#039; always return an &#039;&#039;external_function_parameters&#039;&#039; object. This object is initialized with an associative array. This array contains the parameter descriptions. If the external function have three parameters, this array will have three elements, the keys being the paramters name.&lt;br /&gt;
Each of its element is a parameter description. A parameter can be a list (external_multiple_structure), an object (external_single_structure) or a primary type (external_value).&lt;br /&gt;
&lt;br /&gt;
Our create_groups() function expect one parameter named &#039;&#039;groups&#039;&#039;, so we will first write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns description of method parameters&lt;br /&gt;
     * @return external_function_parameters&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups_parameters() {&lt;br /&gt;
        return new external_function_parameters(&lt;br /&gt;
            array(&lt;br /&gt;
                &#039;groups&#039; =&amp;gt; ...&lt;br /&gt;
                &lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This &#039;&#039;groups&#039;&#039; parameter is a list of group. So we will write :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    ...&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An external_multiple_structure object (list) can be initialized with external_single_structure (object), external_value (primary type) or another external_multiple_structure (list). You will respectively obtain a list of a unique object type, a list of a unique primary type, or a list of a list. These last case being probably bad design.&amp;lt;br/&amp;gt;&lt;br /&gt;
In our case we want a list of group, a group being a object. Have a look on how would describe a group :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;             &lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; ...,&lt;br /&gt;
                        )&lt;br /&gt;
                    )           &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From this code you can guess that a external_single_structure is initialize with an associative array. This array containing the object attibuts.&amp;lt;br/&amp;gt; &lt;br /&gt;
Thus a list of group will be defined :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; ...,&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; ...,&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every of the group attribut are primary type. &#039;&#039;courseid&#039;&#039; is an integer. &#039;&#039;name&#039;&#039; is a string, &#039;&#039;description&#039;&#039; is a string, and &#039;&#039;enrolmentkey&#039;&#039; is also a string. To define a primary type we use the &#039;&#039;external_value&#039;&#039; object. This &#039;&#039;external_value&#039;&#039; is initialize with a non associative array containing three elements:&lt;br /&gt;
# the primary type&lt;br /&gt;
# a human readable description&lt;br /&gt;
# is the parameter optional (if the parameter is mandatory we don&#039;t need this third element)&lt;br /&gt;
&lt;br /&gt;
For example for the &#039;&#039;courseid&#039;&#039; and &#039;&#039;name&#039;&#039; attribut we would define:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;                 &lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),                         &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So our list of object description will be :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;  &lt;br /&gt;
                &#039;groups&#039; =&amp;gt; new external_multiple_structure(&lt;br /&gt;
                    new external_single_structure(&lt;br /&gt;
                        array(&lt;br /&gt;
                            &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                            &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                            &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                            &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                        )&lt;br /&gt;
                    )&lt;br /&gt;
                )          &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now you should be able to understand this parameter description function. You also should be able to deduce how to write the return value description function. &lt;br /&gt;
&lt;br /&gt;
Return value function always return one primary or complex value, so we don&#039;t need to return external_function_parameters object. In our case we want to return the exact same list of groups. The only change being that we want the group to have an id attribut. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
public static function create_groups_returns() {&lt;br /&gt;
        return new external_multiple_structure(&lt;br /&gt;
            new external_single_structure(&lt;br /&gt;
                array(&lt;br /&gt;
                    &#039;id&#039; =&amp;gt; new external_value(PARAM_INT, &#039;group record id&#039;),&lt;br /&gt;
                    &#039;courseid&#039; =&amp;gt; new external_value(PARAM_INT, &#039;id of course&#039;),&lt;br /&gt;
                    &#039;name&#039; =&amp;gt; new external_value(PARAM_TEXT, &#039;multilang compatible name, course unique&#039;),&lt;br /&gt;
                    &#039;description&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group description text&#039;),&lt;br /&gt;
                    &#039;enrolmentkey&#039; =&amp;gt; new external_value(PARAM_RAW, &#039;group enrol secret phrase&#039;),&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here ends the most difficult part of the web service infrastructure implementation. Congratulation!&lt;br /&gt;
&lt;br /&gt;
=== Mandatory, Optional or Default ===&lt;br /&gt;
An attribut can be defined MANDATORY, OPTIONAL, or DEFAULT. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;                 &lt;br /&gt;
                            &#039;yearofstudy&#039; =&amp;gt; new external_value(PARAM_INT, &#039;year of study&#039;,VALUE_DEFAULT, 1979),                        &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The third parameter VALUE_DEFAULT indicates that &#039;yearofstudy&#039; is set to a default value if the attribut is not supply. When you set VALUE_DEFAULT in the description, you must also write a default value as fourth parameter. Here the default value of &#039;yearofstudy&#039; is 1979.&lt;br /&gt;
&lt;br /&gt;
The three values can be understood like it:&lt;br /&gt;
* VALUE_REQUIRED - if the parameter is not supplied, then the server throw an exception&lt;br /&gt;
* VALUE_OPTIONAL - if the parameter is not supplied, then the param has no value&lt;br /&gt;
* VALUE_DEFAULT - if the parameter is not supplied, then the default value is used&lt;br /&gt;
&lt;br /&gt;
== Define the external function ==&lt;br /&gt;
We declared our web service function and we defined the external function parameters and return values. We will now implement the external function. Let&#039;s have a full look to the external function.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
    /**&lt;br /&gt;
     * Create groups&lt;br /&gt;
     * @param array $groups array of group description arrays (with keys groupname and courseid)&lt;br /&gt;
     * @return array of newly created groups&lt;br /&gt;
     */&lt;br /&gt;
    public static function create_groups($groups) { //Don&#039;t forget to set it as static&lt;br /&gt;
        global $CFG, $DB;&lt;br /&gt;
        require_once(&amp;quot;$CFG-&amp;gt;dirroot/group/lib.php&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        $params = self::validate_parameters(self::create_groups_parameters(), array(&#039;groups&#039;=&amp;gt;$groups));&lt;br /&gt;
&lt;br /&gt;
        $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&lt;br /&gt;
        $groups = array();&lt;br /&gt;
&lt;br /&gt;
        foreach ($params[&#039;groups&#039;] as $group) {&lt;br /&gt;
            $group = (object)$group;&lt;br /&gt;
&lt;br /&gt;
            if (trim($group-&amp;gt;name) == &#039;&#039;) {&lt;br /&gt;
                throw new invalid_parameter_exception(&#039;Invalid group name&#039;);&lt;br /&gt;
            }&lt;br /&gt;
            if ($DB-&amp;gt;get_record(&#039;groups&#039;, array(&#039;courseid&#039;=&amp;gt;$group-&amp;gt;courseid, &#039;name&#039;=&amp;gt;$group-&amp;gt;name))) {&lt;br /&gt;
                throw new invalid_parameter_exception(&#039;Group with the same name already exists in the course&#039;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // now security checks&lt;br /&gt;
            $context = get_context_instance(CONTEXT_COURSE, $group-&amp;gt;courseid);&lt;br /&gt;
            self::validate_context($context);&lt;br /&gt;
            require_capability(&#039;moodle/course:managegroups&#039;, $context);&lt;br /&gt;
&lt;br /&gt;
            // finally create the group&lt;br /&gt;
            $group-&amp;gt;id = groups_create_group($group, false);&lt;br /&gt;
            $groups[] = (array)$group;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $transaction-&amp;gt;allow_commit();&lt;br /&gt;
&lt;br /&gt;
        return $groups;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First let&#039;s have a look at &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $params = self::validate_parameters(self::create_groups_parameters(), array(&#039;groups&#039;=&amp;gt;$groups));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This &#039;&#039;validate_parameters&#039;&#039; function validates the external function parameters against the description. It will return an exception if some required parameters are missing, if parameters are not well-formed, and check the parameters validity. The array(&#039;groups&#039;=&amp;gt;$groups) take the expected parameters by the description function. &lt;br /&gt;
&lt;br /&gt;
A very important point: the parameters of your external function (&#039;&#039;$groups&#039;&#039; into &#039;&#039;public static function create_groups(&#039;&#039;&#039;$groups&#039;&#039;&#039;) {&#039;&#039;) should be in the exact same order as the ones into your description function (&#039;&#039;&#039;return new external_function_parameters( array( &#039;&#039;&#039;&#039;groups&#039;&#039;&#039;&#039; =&amp;gt; ... )&#039;&#039;&#039;). I agree that our example function doesn&#039;t give us a good example :)&lt;br /&gt;
&lt;br /&gt;
Then we have the following line&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Our function has for goal to create multiple group. The function is calling multiple time the &#039;&#039;&#039;groups_create_group()&#039;&#039;&#039; core function. If ever one function fail and return an exception, we do not want to commit any change. It&#039;s why we declare this line that suspend any commit till we write the following line&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
 $transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will also notice that our function throws exception. It is automatically handle by Moodle web service servers.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
throw new invalid_parameter_exception(&#039;Group with the same name already exists in the course&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And yet again another important point: the context checking and capability checking happens into the external function. In a long term, in Moodle 2.0, all context/capability checks will disappear from the core functions and will be located into the external functions&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// now security checks&lt;br /&gt;
$context = get_context_instance(CONTEXT_COURSE, $group-&amp;gt;courseid);&lt;br /&gt;
self::validate_context($context);&lt;br /&gt;
require_capability(&#039;moodle/course:managegroups&#039;, $context);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Last point, the return values will be parsed by the Moodle web service servers. Only the required values describe into the function description will be returned. An error will be returned if the external function doesn&#039;t return some required values.&lt;br /&gt;
&lt;br /&gt;
== Add the web service function into a service ==&lt;br /&gt;
In some specific case we could want to set a service by default, so the Moodle administrator doesn&#039;t need to set a new one. We can do that by writing the following code into [http://cvs.moodle.org/moodle/lib/db/ /lib/db/services.php]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
  $services = array(&lt;br /&gt;
      &#039;groupservice&#039; =&amp;gt; array(                                                //the name of the web service&lt;br /&gt;
          &#039;functions&#039; =&amp;gt; array (&#039;moodle_add_groups&#039;, &#039;moodle_create_groups&#039;), //web service functions of this service&lt;br /&gt;
          &#039;requiredcapability&#039; =&amp;gt; &#039;some/capability:specified&#039;,                //if set, the web service user need this capability to access &lt;br /&gt;
                                                                              //any function of this service                   &lt;br /&gt;
          &#039;restrictedusers&#039; = &amp;gt;1,                                             //if enabled, the Moodle administrator must link some user to this service&lt;br /&gt;
                                                                              //into the administration&lt;br /&gt;
          &#039;enabled&#039;=&amp;gt;0,                                                       //if enabled, the service can be reachable on a default installation&lt;br /&gt;
       )&lt;br /&gt;
  );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code we created a service called &#039;&#039;groupservice&#039;&#039;. This service contains two functions &#039;&#039;moodle_add_groups&#039;&#039;/&#039;&#039;moodle_create_groups&#039;&#039;. &amp;lt;br/&amp;gt;&lt;br /&gt;
This possibility to preset a service exists to facilitate the administrator life. He can easily enable a bunch of function. &amp;lt;br/&amp;gt;&lt;br /&gt;
However it is not possible for an administrator to add/remove any function from preset service. For security purpose, it is not a recommended to preset a service.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
* [[Web services]]&lt;br /&gt;
* [[External services security]]&lt;br /&gt;
* [[External services description]]&lt;br /&gt;
* [[Creating_a_web_service_client]]&lt;br /&gt;
* [https://docs.moodle.org/en/Web_Services Web services]&lt;br /&gt;
* [http://moodle.org/mod/forum/discuss.php?d=169078 Using Webservices with Zend Rest Client]&lt;br /&gt;
&lt;br /&gt;
[[Category:Web Services]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29890</id>
		<title>Data manipulation API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29890"/>
		<updated>2011-10-02T19:28:15Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* Getting a particular field value from one record */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The $DB global object is an instance of the moodle_database class, which is defined in [http://cvs.moodle.org/moodle/lib/dml/moodle_database.php?view=markup moodle_database.php]&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
  /// @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;&lt;br /&gt;
  ///                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);&lt;br /&gt;
  ///                        MUST_EXIST means throw exception if no record or multiple records found&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
Each of the following methods return an array of objects. The array is indexed by the first column of the fields returned by the query. Thus to assure consistent data, it appears to be best practice to ensure that your query include an &amp;quot;id column&amp;quot; as the first field. (When developing custom tables, be sure to make id your first column for this reason!)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field, array $values, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following methods return data as key/value pairs in an associative array.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Examples====&lt;br /&gt;
=====moodle_database::get_records()=====&lt;br /&gt;
Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar and jon = doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039; =&amp;gt; &#039;bar AND&#039; , &#039;jon&#039; =&amp;gt; &#039;doe&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar, but only return the fields foo,bar,jon,doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;),null,&#039;foo,bar,jon,doe&#039;);&lt;br /&gt;
///The previous example would cause data issues unless the &#039;foo&#039; field happens to have unique values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select()=====&lt;br /&gt;
Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &#039;doe&#039; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select($table,$select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql()=====&lt;br /&gt;
Get a number of records as an array of objects using a SQL statement. Defined as an abstract function in moodle_database, this method is implemented per database type.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ?&#039;, array(&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = &#039;bar&#039; and bob = &#039;tom&#039;&lt;br /&gt;
///This is somewhat similar to how Drupal makes its queries&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ? AND bob = ?&#039;, array( &#039;bar&#039; , &#039;tom&#039; ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_list()=====&lt;br /&gt;
Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records_list($table, &#039;foo&#039;, array( &#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
///Only returning the fields &#039;id&#039;, &#039;test&#039; and &#039;taco&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records_list($table, &#039;foo&#039;, array( &#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;), null, &#039;id,test,taco&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array where all the given conditions met. &lt;br /&gt;
You can choose the two fields or leave the parameter blank and the method will return the first two columns of the table.&lt;br /&gt;
Returns an associative array. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
///Returning the values from the columns &#039;id&#039; and &#039;tacos&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
$fields = &#039;id, tacos&#039;; ///list of fields to return&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select);&lt;br /&gt;
&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$fields = &#039;id, tacos&#039;;//return these fields&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select,null,$fields);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT * FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT id,tacos FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
  /// @param int $strictness&lt;br /&gt;
  ///   IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;&lt;br /&gt;
  ///   IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);&lt;br /&gt;
  ///   MUST_EXIST means throw exception if no record or multiple records found&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
The method to insert records is called aptly enough, insert_record(). The method accepts 4 parameters, but the fourth, &amp;quot;bulk&amp;quot;, in most implementations is unused.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$lastinsertid = $DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
  /// &lt;br /&gt;
  /// $dataobject is an object containing needed data&lt;br /&gt;
  /// Relies on $dataobject having a variable &amp;quot;id&amp;quot; to&lt;br /&gt;
  /// specify the record to update&lt;br /&gt;
  /// &lt;br /&gt;
  /// @param string $table The database table to be checked against.&lt;br /&gt;
  /// @param object $dataobject An object with contents equal to fieldname=&amp;gt;fieldvalue.&lt;br /&gt;
  ///        Must have an entry for &#039;id&#039; to map to the table specified.&lt;br /&gt;
  /// @param bool $bulk true means repeated updates expected&lt;br /&gt;
  /// @return bool true&lt;br /&gt;
  /// @throws dml_exception if an error occurs.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
Where the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they load all the records in memory at the same time. Under those circumstances, it is highly recommended to use these &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which use one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
foreach ($rs as $record) {&lt;br /&gt;
    // Do whatever you want with this record&lt;br /&gt;
}&lt;br /&gt;
$rs-&amp;gt;close(); // Don&#039;t forget to close the recordset!&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $DB;&lt;br /&gt;
try {&lt;br /&gt;
     $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
     // Insert a record&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;foo&#039;, $object);&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;bar&#039;, $otherobject);&lt;br /&gt;
&lt;br /&gt;
     // Assuming the both inserts work, we get to the following line.&lt;br /&gt;
     $transaction-&amp;gt;allow_commit();&lt;br /&gt;
} catch(Exception $e) {&lt;br /&gt;
     $transaction-&amp;gt;rollback($e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_like($fieldname, $param, $casesensitive = true, $accentsensitive = true, $notlike = false, $escapechar = &#039; \\ &#039;)&lt;br /&gt;
  /// Returns the proper SQL to do LIKE.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29889</id>
		<title>Data manipulation API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29889"/>
		<updated>2011-09-30T19:20:13Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* Updating Records */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The $DB global object is an instance of the moodle_database class, which is defined in [http://cvs.moodle.org/moodle/lib/dml/moodle_database.php?view=markup moodle_database.php]&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
  /// @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;&lt;br /&gt;
  ///                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);&lt;br /&gt;
  ///                        MUST_EXIST means throw exception if no record or multiple records found&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
Each of the following methods return an array of objects. The array is indexed by the first column of the fields returned by the query. Thus to assure consistent data, it appears to be best practice to ensure that your query include an &amp;quot;id column&amp;quot; as the first field. (When developing custom tables, be sure to make id your first column for this reason!)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field, array $values, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following methods return data as key/value pairs in an associative array.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Examples====&lt;br /&gt;
=====moodle_database::get_records()=====&lt;br /&gt;
Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar and jon = doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039; =&amp;gt; &#039;bar AND&#039; , &#039;jon&#039; =&amp;gt; &#039;doe&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar, but only return the fields foo,bar,jon,doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;),null,&#039;foo,bar,jon,doe&#039;);&lt;br /&gt;
///The previous example would cause data issues unless the &#039;foo&#039; field happens to have unique values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select()=====&lt;br /&gt;
Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &#039;doe&#039; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select($table,$select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql()=====&lt;br /&gt;
Get a number of records as an array of objects using a SQL statement. Defined as an abstract function in moodle_database, this method is implemented per database type.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ?&#039;, array(&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = &#039;bar&#039; and bob = &#039;tom&#039;&lt;br /&gt;
///This is somewhat similar to how Drupal makes its queries&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ? AND bob = ?&#039;, array( &#039;bar&#039; , &#039;tom&#039; ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_list()=====&lt;br /&gt;
Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records_list($table, &#039;foo&#039;, array( &#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
///Only returning the fields &#039;id&#039;, &#039;test&#039; and &#039;taco&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records_list($table, &#039;foo&#039;, array( &#039;bar&#039;, &#039;elephant&#039;, &#039;moodle&#039;), null, &#039;id,test,taco&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array where all the given conditions met. &lt;br /&gt;
You can choose the two fields or leave the parameter blank and the method will return the first two columns of the table.&lt;br /&gt;
Returns an associative array. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
///Returning the values from the columns &#039;id&#039; and &#039;tacos&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
$fields = &#039;id, tacos&#039;; ///list of fields to return&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select);&lt;br /&gt;
&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$fields = &#039;id, tacos&#039;;//return these fields&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select,null,$fields);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT * FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT id,tacos FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
The method to insert records is called aptly enough, insert_record(). The method accepts 4 parameters, but the fourth, &amp;quot;bulk&amp;quot;, in most implementations is unused.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$lastinsertid = $DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
  /// &lt;br /&gt;
  /// $dataobject is an object containing needed data&lt;br /&gt;
  /// Relies on $dataobject having a variable &amp;quot;id&amp;quot; to&lt;br /&gt;
  /// specify the record to update&lt;br /&gt;
  /// &lt;br /&gt;
  /// @param string $table The database table to be checked against.&lt;br /&gt;
  /// @param object $dataobject An object with contents equal to fieldname=&amp;gt;fieldvalue.&lt;br /&gt;
  ///        Must have an entry for &#039;id&#039; to map to the table specified.&lt;br /&gt;
  /// @param bool $bulk true means repeated updates expected&lt;br /&gt;
  /// @return bool true&lt;br /&gt;
  /// @throws dml_exception if an error occurs.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
Where the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they load all the records in memory at the same time. Under those circumstances, it is highly recommended to use these &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which use one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
foreach ($rs as $record) {&lt;br /&gt;
    // Do whatever you want with this record&lt;br /&gt;
}&lt;br /&gt;
$rs-&amp;gt;close(); // Don&#039;t forget to close the recordset!&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $DB;&lt;br /&gt;
try {&lt;br /&gt;
     $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
     // Insert a record&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;foo&#039;, $object);&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;bar&#039;, $otherobject);&lt;br /&gt;
&lt;br /&gt;
     // Assuming the both inserts work, we get to the following line.&lt;br /&gt;
     $transaction-&amp;gt;allow_commit();&lt;br /&gt;
} catch(Exception $e) {&lt;br /&gt;
     $transaction-&amp;gt;rollback($e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_like($fieldname, $param, $casesensitive = true, $accentsensitive = true, $notlike = false, $escapechar = &#039; \\ &#039;)&lt;br /&gt;
  /// Returns the proper SQL to do LIKE.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29852</id>
		<title>Data manipulation API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29852"/>
		<updated>2011-09-28T12:10:08Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* moodle_database::get_records_list() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The $DB global object is an instance of the moodle_database class, which is defined in [http://cvs.moodle.org/moodle/lib/dml/moodle_database.php?view=markup moodle_database.php]&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
  /// @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;&lt;br /&gt;
  ///                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);&lt;br /&gt;
  ///                        MUST_EXIST means throw exception if no record or multiple records found&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
Each of the following methods return an array of objects. The array is indexed by the first column of the fields returned by the query. Thus to assure consistent data, it appears to be best practice to ensure that your query include an &amp;quot;id column&amp;quot; as the first field. (When developing custom tables, be sure to make id your first column for this reason!)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field, array $values, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following methods return data as key/value pairs in an associative array.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Examples====&lt;br /&gt;
=====moodle_database::get_records()=====&lt;br /&gt;
Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar and jon = doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039; =&amp;gt; &#039;bar AND&#039; , &#039;jon&#039; =&amp;gt; &#039;doe&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar, but only return the fields foo,bar,jon,doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;),null,&#039;foo,bar,jon,doe&#039;);&lt;br /&gt;
///The previous example would cause data issues unless the &#039;foo&#039; field happens to have unique values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select()=====&lt;br /&gt;
Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &#039;doe&#039; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select($table,$select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql()=====&lt;br /&gt;
Get a number of records as an array of objects using a SQL statement. Defined as an abstract function in moodle_database, this method is implemented per database type.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ?&#039;, array(&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = &#039;bar&#039; and bob = &#039;tom&#039;&lt;br /&gt;
///This is somewhat similar to how Drupal makes its queries&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ? AND bob = ?&#039;, array( &#039;bar&#039; , &#039;tom&#039; ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_list()=====&lt;br /&gt;
Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;,1,&#039;elephant&#039;,&#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records_list($table, &#039;foo&#039;, array( &#039;bar&#039;, 1, &#039;elephant&#039;, &#039;moodle&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;,1,&#039;elephant&#039;,&#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
///Only returning the fields &#039;id&#039;, &#039;test&#039; and &#039;taco&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records_list($table, &#039;foo&#039;, array( &#039;bar&#039;, 1, &#039;elephant&#039;, &#039;moodle&#039;), null, &#039;id,test,taco&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array where all the given conditions met. &lt;br /&gt;
You can choose the two fields or leave the parameter blank and the method will return the first two columns of the table.&lt;br /&gt;
Returns an associative array. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
///Returning the values from the columns &#039;id&#039; and &#039;tacos&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
$fields = &#039;id, tacos&#039;; ///list of fields to return&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select);&lt;br /&gt;
&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$fields = &#039;id, tacos&#039;;//return these fields&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select,null,$fields);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT * FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT id,tacos FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
The method to insert records is called aptly enough, insert_record(). The method accepts 4 parameters, but the fourth, &amp;quot;bulk&amp;quot;, in most implementations is unused.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$lastinsertid = $DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
Where the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they load all the records in memory at the same time. Under those circumstances, it is highly recommended to use these &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which use one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
foreach ($rs as $record) {&lt;br /&gt;
    // Do whatever you want with this record&lt;br /&gt;
}&lt;br /&gt;
$rs-&amp;gt;close(); // Don&#039;t forget to close the recordset!&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $DB;&lt;br /&gt;
try {&lt;br /&gt;
     $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
     // Insert a record&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;foo&#039;, $object);&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;bar&#039;, $otherobject);&lt;br /&gt;
&lt;br /&gt;
     // Assuming the both inserts work, we get to the following line.&lt;br /&gt;
     $transaction-&amp;gt;allow_commit();&lt;br /&gt;
} catch(Exception $e) {&lt;br /&gt;
     $transaction-&amp;gt;rollback($e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_like($fieldname, $param, $casesensitive = true, $accentsensitive = true, $notlike = false, $escapechar = &#039; \\ &#039;)&lt;br /&gt;
  /// Returns the proper SQL to do LIKE.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29851</id>
		<title>Data manipulation API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29851"/>
		<updated>2011-09-28T12:09:19Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* moodle_database::get_records_sql() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The $DB global object is an instance of the moodle_database class, which is defined in [http://cvs.moodle.org/moodle/lib/dml/moodle_database.php?view=markup moodle_database.php]&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
  /// @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;&lt;br /&gt;
  ///                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);&lt;br /&gt;
  ///                        MUST_EXIST means throw exception if no record or multiple records found&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
Each of the following methods return an array of objects. The array is indexed by the first column of the fields returned by the query. Thus to assure consistent data, it appears to be best practice to ensure that your query include an &amp;quot;id column&amp;quot; as the first field. (When developing custom tables, be sure to make id your first column for this reason!)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field, array $values, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following methods return data as key/value pairs in an associative array.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Examples====&lt;br /&gt;
=====moodle_database::get_records()=====&lt;br /&gt;
Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar and jon = doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039; =&amp;gt; &#039;bar AND&#039; , &#039;jon&#039; =&amp;gt; &#039;doe&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar, but only return the fields foo,bar,jon,doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;),null,&#039;foo,bar,jon,doe&#039;);&lt;br /&gt;
///The previous example would cause data issues unless the &#039;foo&#039; field happens to have unique values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select()=====&lt;br /&gt;
Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &#039;doe&#039; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select($table,$select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql()=====&lt;br /&gt;
Get a number of records as an array of objects using a SQL statement. Defined as an abstract function in moodle_database, this method is implemented per database type.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ?&#039;, array(&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = &#039;bar&#039; and bob = &#039;tom&#039;&lt;br /&gt;
///This is somewhat similar to how Drupal makes its queries&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ? AND bob = ?&#039;, array( &#039;bar&#039; , &#039;tom&#039; ));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_list()=====&lt;br /&gt;
Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;,1,&#039;elephant&#039;,&#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table, &#039;foo&#039;, array( &#039;bar&#039;, 1, &#039;elephant&#039;, &#039;moodle&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;,1,&#039;elephant&#039;,&#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
///Only returning the fields &#039;id&#039;, &#039;test&#039; and &#039;taco&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table, &#039;foo&#039;, array( &#039;bar&#039;, 1, &#039;elephant&#039;, &#039;moodle&#039;)null, &#039;id,test,taco&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array where all the given conditions met. &lt;br /&gt;
You can choose the two fields or leave the parameter blank and the method will return the first two columns of the table.&lt;br /&gt;
Returns an associative array. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
///Returning the values from the columns &#039;id&#039; and &#039;tacos&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
$fields = &#039;id, tacos&#039;; ///list of fields to return&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select);&lt;br /&gt;
&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$fields = &#039;id, tacos&#039;;//return these fields&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select,null,$fields);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT * FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT id,tacos FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
The method to insert records is called aptly enough, insert_record(). The method accepts 4 parameters, but the fourth, &amp;quot;bulk&amp;quot;, in most implementations is unused.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$lastinsertid = $DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
Where the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they load all the records in memory at the same time. Under those circumstances, it is highly recommended to use these &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which use one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
foreach ($rs as $record) {&lt;br /&gt;
    // Do whatever you want with this record&lt;br /&gt;
}&lt;br /&gt;
$rs-&amp;gt;close(); // Don&#039;t forget to close the recordset!&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $DB;&lt;br /&gt;
try {&lt;br /&gt;
     $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
     // Insert a record&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;foo&#039;, $object);&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;bar&#039;, $otherobject);&lt;br /&gt;
&lt;br /&gt;
     // Assuming the both inserts work, we get to the following line.&lt;br /&gt;
     $transaction-&amp;gt;allow_commit();&lt;br /&gt;
} catch(Exception $e) {&lt;br /&gt;
     $transaction-&amp;gt;rollback($e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_like($fieldname, $param, $casesensitive = true, $accentsensitive = true, $notlike = false, $escapechar = &#039; \\ &#039;)&lt;br /&gt;
  /// Returns the proper SQL to do LIKE.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29850</id>
		<title>Data manipulation API</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Data_manipulation_API&amp;diff=29850"/>
		<updated>2011-09-28T12:08:29Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: /* moodle_database::get_records_sql() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Moodle_2.0}}This page describes the functions available to access data in the Moodle database. You should &#039;&#039;&#039;exclusively&#039;&#039;&#039; use these functions in order to retrieve or modify database content because these functions provide a high level of abstraction and guarantee that your database manipulation will work against different RDBMSes.&lt;br /&gt;
&lt;br /&gt;
Where possible, tricks and examples will be documented here in order to make developers&#039; lives a bit easier. Of course, feel free to clarify, complete and add more information to  this documentation. It will be welcome, absolutely!&lt;br /&gt;
&lt;br /&gt;
== Main info ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important note:&#039;&#039;&#039; All the functions shown on this page are for use in &#039;&#039;&#039;Moodle 2.0 upwards&#039;&#039;&#039;, where we changed the [[DB layer 2.0|DB layer]] to support some new features. If you need information for previous Moodle version, take a look to the [[DML functions - pre 2.0|DML functions - pre 2.0]] page. For a detailed reference of changes, see the [[DB layer 2.0 migration docs|migration docs]].&lt;br /&gt;
&lt;br /&gt;
* All the function calls on this page are public methods of the $DB global object, so you&#039;ll need to &amp;quot;import&amp;quot; it within your functions (not needed in global scripts) with one simple:&lt;br /&gt;
&amp;lt;code php&amp;gt;global $DB;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The $DB global object is an instance of the moodle_database class, which is defined in [http://cvs.moodle.org/moodle/lib/dml/moodle_database.php?view=markup moodle_database.php]&lt;br /&gt;
* All the $table parameters in the functions are meant to be the table name &#039;&#039;without&#039;&#039; prefixes.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;id&#039;=&amp;gt;&#039;1&#039;);&amp;lt;/code&amp;gt;&lt;br /&gt;
* When using the xxx_sql() functions, table names must be enclosed between curly braces.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE id = ?&#039;, array(1));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $conditions parameters in the functions are arrays of fieldname=&amp;gt;fieldvalue elements.&lt;br /&gt;
&amp;lt;code php&amp;gt;$user = $DB-&amp;gt;get_record(&#039;user&#039;, array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&amp;lt;/code&amp;gt;&lt;br /&gt;
* All the $params parameters in the functions are arrays of values used to fill placeholders in SQL statements. Both the question mark and named placeholders can be used. Note that named params &#039;&#039;&#039;must be unique&#039;&#039;&#039; even if the value passed is the same.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// Question mark placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = ? AND lastname = ?&#039;, &lt;br /&gt;
                       array(&#039;Martin&#039;, &#039;Dougiamas&#039;));&lt;br /&gt;
&lt;br /&gt;
/// Named placeholders:&lt;br /&gt;
   $DB-&amp;gt;get_record_sql(&#039;SELECT * FROM {user} WHERE firstname = :firstname AND lastname = :lastname&#039;,&lt;br /&gt;
                       array(&#039;firstname&#039;=&amp;gt;&#039;Martin&#039;, &#039;lastname&#039;=&amp;gt;&#039;Dougiamas&#039;));&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The functions ==&lt;br /&gt;
&lt;br /&gt;
===Seeing how many records match a given criteria===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;count_records($table, array $conditions=null) &lt;br /&gt;
  /// Count the records in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;count_records_select($table, $select, array $params=null, $countitem=&amp;quot;COUNT(&#039;x&#039;)&amp;quot;) &lt;br /&gt;
  /// Count the records in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;count_records_sql($sql, array $params=null) &lt;br /&gt;
  /// Get the result of a SQL SELECT COUNT(...) query.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Seeing if one record exists===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;record_exists($table, array $conditions=null) &lt;br /&gt;
  /// Test whether a record exists in a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;record_exists_select($table, $select, array $params=null) &lt;br /&gt;
  /// Test whether any records exists in a table which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;record_exists_sql($sql, array $params=null) &lt;br /&gt;
  /// Test whether a SQL SELECT statement returns any records.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a single record===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_record($table, array $conditions, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING) &lt;br /&gt;
  /// Get a single database record as an object where all the given conditions met.&lt;br /&gt;
  /// @param int $strictness IGNORE_MISSING means compatible mode, false returned if record not found, debug message if more found;&lt;br /&gt;
  ///                        IGNORE_MULTIPLE means return first, ignore multiple records found(not recommended);&lt;br /&gt;
  ///                        MUST_EXIST means throw exception if no record or multiple records found&lt;br /&gt;
o $DB-&amp;gt;get_record_select($table, $select, array $params=null, $fields=&#039;*&#039;, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_record_sql($sql, array $params=null, $strictness=IGNORE_MISSING)&lt;br /&gt;
  /// Get a single database record as an object using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting an array of records===&lt;br /&gt;
Each of the following methods return an array of objects. The array is indexed by the first column of the fields returned by the query. Thus to assure consistent data, it appears to be best practice to ensure that your query include an &amp;quot;id column&amp;quot; as the first field. (When developing custom tables, be sure to make id your first column for this reason!)&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get a number of records as an array of objects using a SQL statement.&lt;br /&gt;
o $DB-&amp;gt;get_records_list($table, $field, array $values, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following methods return data as key/value pairs in an associative array.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_records_menu($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_records_select_menu($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_records_sql_menu($sql, array $params=null, $limitfrom=0, $limitnum=0)&lt;br /&gt;
  /// Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Examples====&lt;br /&gt;
=====moodle_database::get_records()=====&lt;br /&gt;
Get a number of records as an array of objects where all the given conditions met.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar and jon = doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039; =&amp;gt; &#039;bar AND&#039; , &#039;jon&#039; =&amp;gt; &#039;doe&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where foo = bar, but only return the fields foo,bar,jon,doe&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table,array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;),null,&#039;foo,bar,jon,doe&#039;);&lt;br /&gt;
///The previous example would cause data issues unless the &#039;foo&#039; field happens to have unique values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select()=====&lt;br /&gt;
Get a number of records as an array of objects which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &#039;doe&#039; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select($table,$select);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql()=====&lt;br /&gt;
Get a number of records as an array of objects using a SQL statement. Defined as an abstract function in moodle_database, this method is implemented per database type.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = bar&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ?&#039;,array(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
///Get all records from &#039;table&#039; where foo = &#039;bar&#039; and bob = &#039;tom&#039;&lt;br /&gt;
///This is somewhat similar to how Drupal makes its queries&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql(&#039;SELECT * FROM table WHERE foo = ? AND bob = ?&#039;, array( &#039;bar&#039; , &#039;tom&#039; );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_list()=====&lt;br /&gt;
Get a number of records as an array of objects where one field match one list of values.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;,1,&#039;elephant&#039;,&#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table, &#039;foo&#039;, array( &#039;bar&#039;, 1, &#039;elephant&#039;, &#039;moodle&#039;));&lt;br /&gt;
&lt;br /&gt;
///Get all records where the values(&#039;bar&#039;,1,&#039;elephant&#039;,&#039;moodle&#039;) are found in the field &#039;foo&#039;&lt;br /&gt;
///Only returning the fields &#039;id&#039;, &#039;test&#039; and &#039;taco&#039;&lt;br /&gt;
$result = $DB-&amp;gt;get_records($table, &#039;foo&#039;, array( &#039;bar&#039;, 1, &#039;elephant&#039;, &#039;moodle&#039;)null, &#039;id,test,taco&#039;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array where all the given conditions met. &lt;br /&gt;
You can choose the two fields or leave the parameter blank and the method will return the first two columns of the table.&lt;br /&gt;
Returns an associative array. &lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
///Get all records from table &#039;foo&#039; where column &#039;foo&#039; is equal to the value &#039;bar&#039;&lt;br /&gt;
///Returning the values from the columns &#039;id&#039; and &#039;tacos&#039;&lt;br /&gt;
$table = &#039;foo&#039;; ///name of table&lt;br /&gt;
$conditions = array(&#039;foo&#039;=&amp;gt;&#039;bar&#039;); ///the name of the field (key) and the desired value&lt;br /&gt;
$fields = &#039;id, tacos&#039;; ///list of fields to return&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_menu($table,$conditions));&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_select_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records where jon = &#039;doe&#039; and bob is not = &#039;tom&#039;&lt;br /&gt;
///The &#039;select&#039; parameter is (if not empty) is dropped directly into the WHERE clause without alteration.&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select);&lt;br /&gt;
&lt;br /&gt;
$table = &#039;foo&#039;;&lt;br /&gt;
$select = &#039;jon = &amp;quot;doe&amp;quot; AND bob != &amp;quot;tom&amp;quot; &#039;; //is put into the where clause&lt;br /&gt;
$fields = &#039;id, tacos&#039;;//return these fields&lt;br /&gt;
$result = $DB-&amp;gt;get_records_select_menu($table,$select,null,$fields);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====moodle_database::get_records_sql_menu()=====&lt;br /&gt;
Get the first two columns from a number of records as an associative array using a SQL statement.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT * FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
///Get all records from table foo where bar = 6&lt;br /&gt;
$sql = &#039;SELECT id,tacos FROM foo WHERE bar = ?&#039;;&lt;br /&gt;
$params = array(6);&lt;br /&gt;
&lt;br /&gt;
$result = $DB-&amp;gt;get_records_sql_menu($sql,$params);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result of this last example will look something like:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
/// The value of the id field  is 909 and the value of the &#039;tacos&#039; column is 6&lt;br /&gt;
array(1) { [909]=6 } &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from one record===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_field($table, $return, array $conditions)&lt;br /&gt;
  /// Get a single field value from a table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_field_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Get a single field value from a table record which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_field_sql($sql, array $params=null)&lt;br /&gt;
  /// Get a single field value (first field) using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Getting a particular field value from various records===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_select($table, $return, $select, array $params=null)&lt;br /&gt;
  /// Selects records and return values of chosen field as an array which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_fieldset_sql($sql, array $params=null)&lt;br /&gt;
  /// Selects records and return values (first field) as an array using a SQL statement.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Setting a particular field in the database===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;set_field($table, $newfield, $newvalue, array $conditions=null)&lt;br /&gt;
  /// Set a single field in every table record where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;set_field_select($table, $newfield, $newvalue, $select, array $params=null)&lt;br /&gt;
  /// Set a single field in every table record which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Deleting Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;delete_records($table, array $conditions=null) &lt;br /&gt;
  /// Delete the records from a table where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;delete_records_select($table, $select, array $params=null)&lt;br /&gt;
  /// Delete one or more records from a table which match a particular WHERE clause.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Inserting Records===&lt;br /&gt;
The method to insert records is called aptly enough, insert_record(). The method accepts 4 parameters, but the fourth, &amp;quot;bulk&amp;quot;, in most implementations is unused.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;insert_record($table, $dataobject, $returnid=true, $bulk=false) &lt;br /&gt;
  /// Insert a record into a table and return the &amp;quot;id&amp;quot; field if required.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record, false);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$record = new stdClass();&lt;br /&gt;
$record-&amp;gt;name         = &#039;overview&#039;;&lt;br /&gt;
$record-&amp;gt;displayorder = &#039;10000&#039;;&lt;br /&gt;
$lastinsertid = $DB-&amp;gt;insert_record(&#039;quiz_report&#039;, $record);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Updating Records===&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;update_record($table, $dataobject, $bulk=false)&lt;br /&gt;
  /// Update a record in a table.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Recordsets===&lt;br /&gt;
&lt;br /&gt;
Where the number of records to be retrieved from DB is high, the &#039;&#039;&#039;get_records_xxx()&#039;&#039;&#039; functions above are far from optimal, because they load all the records in memory at the same time. Under those circumstances, it is highly recommended to use these &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions instead, which use one nice mechanism to iterate over all the target records and save a lot of memory.&lt;br /&gt;
&lt;br /&gt;
Only one thing is &#039;&#039;&#039;absolutely important&#039;&#039;&#039;: Don&#039;t forget to close the recordsets after using them! (This will free up a lot of resources in the RDBMS).&lt;br /&gt;
&lt;br /&gt;
Here is the general way to iterate over records using the &#039;&#039;&#039;get_recordset_xxx()&#039;&#039;&#039; functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$rs = $DB-&amp;gt;get_recordset(....) {&lt;br /&gt;
foreach ($rs as $record) {&lt;br /&gt;
    // Do whatever you want with this record&lt;br /&gt;
}&lt;br /&gt;
$rs-&amp;gt;close(); // Don&#039;t forget to close the recordset!&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And this is the list of available functions (100% paired with the get_records_xxx() above):&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;get_recordset($table, array $conditions=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where all the given conditions met.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_select($table, $select, array $params=null, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=0, $limitnum=0) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset which match a particular WHERE clause.&lt;br /&gt;
o $DB-&amp;gt;get_recordset_sql($sql, array $params=null, $limitfrom=0, $limitnum=0);&lt;br /&gt;
  /// Get a number of records as a moodle_recordset using a SQL statement.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;get_recordset_list($table, $field=&#039;&#039;, $values=&#039;&#039;, $sort=&#039;&#039;, $fields=&#039;*&#039;, $limitfrom=&#039;&#039;, $limitnum=&#039;&#039;) &lt;br /&gt;
  /// Get a number of records as a moodle_recordset where one field matches one list of values.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Delegated transactions===&lt;br /&gt;
&lt;br /&gt;
* Please note some databases do not support transactions (such as the MyISAM MySQL database engine), however all server administrators are strongly encouraged to migrate to databases that support transactions (such as the InnoDB MySQL database engine).&lt;br /&gt;
* Previous versions supported only one level of transaction. Since Moodle 2.0, the DML layer emulates delegated transactions that allow nesting of transactions.&lt;br /&gt;
* Transactions should not be used much in Moodle core; they are intended for various plugins such as web services, enrol and auth plugins.&lt;br /&gt;
* Some subsystems (such as messaging) do not support transactions because is it is not possible to rollback in external systems.&lt;br /&gt;
&lt;br /&gt;
A transaction is started by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and finished by:&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
$transaction-&amp;gt;allow_commit();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Usually a transaction is rolled back when an exception is thrown. &amp;lt;code&amp;gt;$transaction-&amp;gt;rollback($ex);&amp;lt;/code&amp;gt; must be used very carefully because it might break compatibility with databases that do not support transactions. Transactions cannot be used as part of expected code flow; they can be used only as an emergency protection of data consistency.&lt;br /&gt;
&lt;br /&gt;
See more details in [[DB layer 2.0 delegated transactions]] or MDL-20625.&lt;br /&gt;
&lt;br /&gt;
====Example(s)====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
global $DB;&lt;br /&gt;
try {&lt;br /&gt;
     $transaction = $DB-&amp;gt;start_delegated_transaction();&lt;br /&gt;
     // Insert a record&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;foo&#039;, $object);&lt;br /&gt;
     $DB-&amp;gt;insert(&#039;bar&#039;, $otherobject);&lt;br /&gt;
&lt;br /&gt;
     // Assuming the both inserts work, we get to the following line.&lt;br /&gt;
     $transaction-&amp;gt;allow_commit();&lt;br /&gt;
} catch(Exception $e) {&lt;br /&gt;
     $transaction-&amp;gt;rollback($e);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Helper Functions===&lt;br /&gt;
&lt;br /&gt;
In order have real cross-db compatibility, there are some helper functions used to build SQL fragments based on the DB Moodle is running. Using them we&#039;ll avoid conditional queries here and there and have those &amp;quot;incompatibilities&amp;quot; fixed once and for ever.&lt;br /&gt;
&amp;lt;code php&amp;gt;&lt;br /&gt;
o $DB-&amp;gt;sql_bitand($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise AND &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitnot($int1) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise NOT &lt;br /&gt;
  /// operation with 1 integer.&lt;br /&gt;
o $DB-&amp;gt;sql_bitor($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise OR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
o $DB-&amp;gt;sql_bitxor($int1, $int2) &lt;br /&gt;
  /// Returns the SQL text to be used in order to perform one bitwise XOR &lt;br /&gt;
  /// operation between 2 integers.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_null_from_clause()&lt;br /&gt;
  /// Returns the FROM clause required by some DBs in all SELECT statements.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_ceil($fieldname)&lt;br /&gt;
  /// Returns the correct CEIL expression applied to fieldname.&lt;br /&gt;
o $DB-&amp;gt;sql_like($fieldname, $param, $casesensitive = true, $accentsensitive = true, $notlike = false, $escapechar = &#039; \\ &#039;)&lt;br /&gt;
  /// Returns the proper SQL to do LIKE.&lt;br /&gt;
o $DB-&amp;gt;sql_length($fieldname)&lt;br /&gt;
  /// Returns the SQL text to be used to calculate the length in characters of one expression.&lt;br /&gt;
o $DB-&amp;gt;sql_modulo($int1, $int2)&lt;br /&gt;
  /// Returns the SQL text to be used in order to calculate module - remainder after division&lt;br /&gt;
o $DB-&amp;gt;sql_position($needle, $haystack)&lt;br /&gt;
  /// Returns the SQL for returning searching one string for the location of another.&lt;br /&gt;
  /// Note: If using placeholders BOTH in $needle and $haystack, they MUST be named placeholders.&lt;br /&gt;
o $DB-&amp;gt;sql_substr($expr, $start, $length=false)&lt;br /&gt;
  /// Returns the proper substr() SQL text used to extract substrings from DB.&lt;br /&gt;
  /// Note: This fuction has changed in Moodle 2.0 and now at least 2 params are mandatory.&lt;br /&gt;
  /// Note: Now it returns the whole SQL text to be used instead of only the function name.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2int($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to INTEGER.&lt;br /&gt;
o $DB-&amp;gt;sql_cast_char2real($fieldname, $text=false)&lt;br /&gt;
  /// Returns the SQL to be used in order to CAST one CHAR column to REAL number.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_compare_text($fieldname, $numchars=32) &lt;br /&gt;
  /// Returns the SQL text to be used to compare one TEXT (clob) column.&lt;br /&gt;
  /// with one VARCHAR column.&lt;br /&gt;
o $DB-&amp;gt;sql_order_by_text($fieldname, $numchars=32)&lt;br /&gt;
  /// Returns the SQL text to be used to order by one TEXT (clob) column.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_concat()&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed.&lt;br /&gt;
o $DB-&amp;gt;sql_concat_join($separator=&amp;quot;&#039; &#039;&amp;quot;, $elements=array())&lt;br /&gt;
  /// Returns the proper SQL to do CONCAT between the elements passed using one separator.&lt;br /&gt;
o $DB-&amp;gt;sql_fullname($first=&#039;firstname&#039;, $last=&#039;lastname&#039;)&lt;br /&gt;
  /// Returns the proper SQL to concatenate $firstname and $lastname.&lt;br /&gt;
 &lt;br /&gt;
o $DB-&amp;gt;sql_isempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is empty.&lt;br /&gt;
o $DB-&amp;gt;sql_isnotempty($tablename, $fieldname, $nullablefield, $textfield)&lt;br /&gt;
  /// Returns the proper SQL to know if one field is not empty.&lt;br /&gt;
o $DB-&amp;gt;sql_empty()&lt;br /&gt;
  /// Returns the empty string char used by every supported DB.&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
&lt;br /&gt;
* [[DML exceptions|DML exceptions]]: New DML code is throwing exceptions instead of returning false if anything goes wrong&lt;br /&gt;
* [[DML drivers|DML drivers]]: Database drivers for new DML layer&lt;br /&gt;
* [[DML functions - pre 2.0|DML functions - pre 2.0]]: &#039;&#039;&#039;(deprecated!)&#039;&#039;&#039; For information valid before Moodle 2.0.&lt;br /&gt;
* [[DDL functions|DDL functions]]: Where all the functions used to handle DB objects ([[wikipedia:Data_Definition_Language|DDL]]) are defined.&lt;br /&gt;
* [[DB layer 2.0 examples|DB layer 2.0 examples]]: To see some code examples using various DML functions.&lt;br /&gt;
* [[DB layer 2.0 migration docs|DB layer 2.0 migration docs]]: Information about how to modify your code to work with the new Moodle 2.0 DB layer.&lt;br /&gt;
* [[DTL functions|DTL functions]]: Exporting, importing and moving of data stored in SQL databases&lt;br /&gt;
&lt;br /&gt;
[[Category:DB]]&lt;br /&gt;
[[Category:XMLDB]]&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Talk:Subplugins&amp;diff=29840</id>
		<title>Talk:Subplugins</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Talk:Subplugins&amp;diff=29840"/>
		<updated>2011-09-24T14:19:08Z</updated>

		<summary type="html">&lt;p&gt;Fp2011: more details please !&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;quot;A sub-plugin has the same structure as a regular plugin. It will have a version.php, a lang directory, and can have a db directory with an install.xml and all the other hooks you&#039;d expect to see used in any other type of plugin, such as an activity, block, or admin report.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This part is unclear. None of the actual subplugins of the Moodle distribution have this structure. What hooks precisely can be used in a subplugin ? What file names, what function names, what classes are needed to get it all working ?&lt;br /&gt;
&lt;br /&gt;
Thanks,&lt;br /&gt;
&lt;br /&gt;
[[User:F P|F P]] 22:19, 24 September 2011 (WST)&lt;/div&gt;</summary>
		<author><name>Fp2011</name></author>
	</entry>
</feed>