diff --git a/README.md b/README.md index 7984364..07153f4 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,32 @@ -# oracle-database-azure-samples +# Oracle Database@Azure Samples -[![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://img.shields.io/badge/license-UPL-green) - -## THIS IS A NEW, BLANK REPO THAT IS NOT READY FOR USE YET. PLEASE CHECK BACK SOON! +[![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://img.shields.io/badge/license-UPL-green) ## Introduction - -MISSING +Oracle Database@Azure brings Oracle's best databases - Exadata and Autonomous Database - to Microsoft Azure as a native Azure services. Modernize and deliver powerful new apps that leverage Oracle Database 23ai and Azure services: +* Build new cloud native apps using Azure services, such as Azure Kubernetes and Azure OpenAI, with Oracle Autonomous Database. +* Enhance existing apps with natural language and other generative AI capabilities. +* Quickly react to business demands using one converged, fully automated database that’s optimized for all workloads and data formats. ## Getting Started +* [Install the Azure CLI](https://learn.microsoft.com/en-us/cli/azure/) +* [Deploy a new Oracle Autonomous Database using the Azure CLI](azure-cli/deploy-adb.md) +* Get started with Select AI ([enable access](sql/select-ai-admin-enable.sql) | [samples](sql/select-ai-get-started.sql)) -MISSING + +## Contributing @@ -38,11 +39,10 @@ Please consult the [security guide](./SECURITY.md) for our responsible security vulnerability disclosure process. ## License - Copyright (c) 2024 Oracle and/or its affiliates. Licensed under the Universal Permissive License (UPL), Version 1.0. See [LICENSE](LICENSE.txt) for more details. -ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. +ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. diff --git a/azure-cli/config b/azure-cli/config new file mode 100644 index 0000000..4e0c32a --- /dev/null +++ b/azure-cli/config @@ -0,0 +1,6 @@ +# update the values below to match your requirements +LOCATION="eastus" +RESOURCE_GROUP="resource-group-name-goes-here" +VNET_ID="vnet-resource-name-goes-here" +SUBNET_ID="subnet-resource-name-goes-here" +ADB_NAME="adb-name-goes-here" \ No newline at end of file diff --git a/azure-cli/deploy-adb.md b/azure-cli/deploy-adb.md new file mode 100644 index 0000000..4dd1c1b --- /dev/null +++ b/azure-cli/deploy-adb.md @@ -0,0 +1,52 @@ +# Oracle Database@Azure: Create an Autonomous Database +The steps below show how to create an Autonomous Database using the Azure CLI. You will need to [install the Azure CLI](https://learn.microsoft.com/en-us/cli/azure/) prior to running thru this example. + +Run the examples below at a command prompt. + +> [!NOTE] +> See the [details for onboarding Autonomous Database](https://learn.microsoft.com/en-us/azure/oracle/oracle-db/onboard-oracle-database) + +## Deploy your Autonomous Database +Start by logging into Azure: +```bash +az login +``` + +Edit the [config file](./config) based on your deployment. These variables will be used by the Azure CLI. +```bash +LOCATION="eastus" +RESOURCE_GROUP="resource-group-name-goes-here" +VNET_ID="vnet-resource-name-goes-here" +SUBNET_ID="subnet-resource-name-goes-here" +ADB_NAME="adb-name-goes-here" +``` +The VNET and SUBNET IDs must be fully qualified IDs. For example: +* **VNET_ID=**`"/subscriptions/99d4fb0e-ac2.../resourceGroups/your-resource-group/providers/Microsoft.Network/virtualNetworks/your-vnet"` +* **SUBNET_ID=**`"/subscriptions/99d4fb0e-ac2.../resourceGroups/your-resource-group/providers/Microsoft.Network/virtualNetworks/your-vnet/subnets/your-subnet"` + +After updating the config file, create a new Autonomous Database by running [`./deploy-adb.sh`](./deploy-adb.sh) from the command line. You can also modify other database properties by editing the deployment script. + +The script will prompte you for the Autonomous Database **ADMIN** user password. Enter a complex password. + +After a few minutes, review your newly created database: +```bash +az oracle-database autonomous-database show \ +--autonomousdatabasename $ADB_NAME \ +--resource-group $RESOURCE_GROUP +``` + +## Delete an Autonomous Database +You can run the following command to an Autonomous Database: + +```bash +az oracle-database autonomous-database delete \ +--autonomousdatabasename $ADB_NAME \ +--resource-group $RESOURCE_GROUP \ +--no-wait false +``` + + + +
+Copyright (c) 2024 Oracle and/or its affiliates.
+Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ diff --git a/azure-cli/deploy-adb.sh b/azure-cli/deploy-adb.sh new file mode 100755 index 0000000..ccad810 --- /dev/null +++ b/azure-cli/deploy-adb.sh @@ -0,0 +1,22 @@ +# ensure you update the config file to match your deployment prior to running the deployment + +source ./config + +az oracle-database autonomous-database create \ +--location $LOCATION \ +--autonomousdatabasename $ADB_NAME \ +--resource-group $RESOURCE_GROUP \ +--subnet-id $SUBNET_ID \ +--display-name $ADB_NAME \ +--compute-model ECPU \ +--compute-count 2 \ +--cpu-auto-scaling true \ +--data-storage-size-in-gbs 500 \ +--license-model BringYourOwnLicense \ +--db-workload OLTP \ +--db-version 23ai \ +--character-set AL32UTF8 \ +--ncharacter-set AL16UTF16 \ +--vnet-id $VNET_ID \ +--regular \ +--admin-password \ No newline at end of file diff --git a/sql/config.sql b/sql/config.sql new file mode 100644 index 0000000..500f8c9 --- /dev/null +++ b/sql/config.sql @@ -0,0 +1,11 @@ +/* +Enter the configuration information for your Azure OpenAI deployment +*/ + +-- The endpoint should be the servername only. For example, myopenai.openai.azure.com +define azureOpenAIEndpoint='your-endpoint.openai.azure.com' +define userName='moviestream' +define profileName='gpt4o' +define azureOpenAICredentialName='azure_cred4o' +define azureOpenAIResourceName='your-resource-name' +define azureOpenAIDeploymentName='your-deployment-name' diff --git a/sql/security-vpd.sql b/sql/security-vpd.sql new file mode 100644 index 0000000..d2d65e2 --- /dev/null +++ b/sql/security-vpd.sql @@ -0,0 +1,44 @@ +CREATE TABLE "MOVIESTREAM"."VGSALES" + ( "NAME" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "PLATFORM" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "YEAR_OF_RELEASE" NUMBER, + "GENRE" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "PUBLISHER" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "NA_SALES" NUMBER, + "EU_SALES" NUMBER, + "JP_SALES" NUMBER, + "OTHER_SALES" NUMBER, + "GLOBAL_SALES" NUMBER, + "CRITIC_SCORE" NUMBER, + "CRITIC_COUNT" NUMBER, + "USER_SCORE" NUMBER, + "USER_COUNT" NUMBER, + "DEVELOPER" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP", + "RATING" VARCHAR2(4000 BYTE) COLLATE "USING_NLS_COMP" + ) DEFAULT COLLATION "USING_NLS_COMP" ; + +CREATE OR REPLACE FUNCTION hide_eu ( + v_schema IN VARCHAR2, + v_objname IN VARCHAR2) + +RETURN VARCHAR2 AS +con VARCHAR2 (200); + +BEGIN + con := 'Year_of_release=2009'; + RETURN (con); +END hide_eu; + +BEGIN + dbms_rls.drop_policy(object_schema => 'MOVIESTREAM',object_name=>'VGSALES',policy_name=>'hide_year'); +end; + +BEGIN + DBMS_RLS.ADD_POLICY( + object_schema => 'MOVIESTREAM', + object_name => 'VGSALES', + policy_name => 'hide_year', + policy_function => 'hide_eu', + sec_relevant_cols =>'eu_sales', + sec_relevant_cols_opt => dbms_rls.ALL_ROWS); +END; \ No newline at end of file diff --git a/sql/select-ai-admin-enable.sql b/sql/select-ai-admin-enable.sql new file mode 100644 index 0000000..649480d --- /dev/null +++ b/sql/select-ai-admin-enable.sql @@ -0,0 +1,15 @@ +/* Run this script as the Autonomous Database ADMIN user */ +/* You must enable network access to Azure OpenAI for the database user that will be accessing the service */ + +-- config.sql contains the endpoints, resource groups and other settings required to connect to your Azure OpenAI deployment +@./config.sql + +BEGIN + DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( + host => '&azureOpenAIEndpoint', + ace => xs$ace_type(privilege_list => xs$name_list('http'), + principal_name => '&userName', + principal_type => xs_acl.ptype_db) + ); +END; +/ \ No newline at end of file diff --git a/sql/select-ai-get-started.sql b/sql/select-ai-get-started.sql new file mode 100644 index 0000000..5daad59 --- /dev/null +++ b/sql/select-ai-get-started.sql @@ -0,0 +1,210 @@ +/* Run this script as the Autonomous Database database user that will be access Azure OpenAI */ + +-- config.sql contains the endpoints, resource groups and other settings required to connect to your Azure OpenAI deployment +@./config.sql + +ACCEPT azureOpenAIKey CHAR PROMPT 'Enter your Azure OpenAI Key: ' HIDE + +-- Create a credential that allows the user to access the Azure OpenAI endpoint +BEGIN + dbms_cloud.create_credential( + credential_name => '&azureOpenAICredentialName', + username => 'AZURE_OPENAI', + password => '&azureOpenAIKey'); +END; +/ + +/* + A Select AI profile describes the LLM you will use plus information that will be used for natural language queries. You can create as many + AI profiles as you need. You may want to try different models to see their effectiveness, expose profiles to different user groups, etc.: + 1. For Azure OpenAI, a deployment was created that is using the gpt-4o model + 2. The object list contains the tables that will be the targets for natural language queries +*/ + +begin + -- recreate the profile + dbms_cloud_ai.drop_profile( + profile_name => '&profileName', + force => true + ); + + -- create an AI profile + dbms_cloud_ai.create_profile( + profile_name => '&profileName', + attributes => + '{"provider": "azure", + "azure_resource_name": "&azureOpenAIResourceName", + "azure_deployment_name": "&azureOpenAIDeploymentName", + "credential_name": "&azureOpenAICredentialName", + "comments":"true", + "object_list": [ + {"owner": "&userName", "name": "GENRE"}, + {"owner": "&userName", "name": "CUSTOMER"}, + {"owner": "&userName", "name": "PIZZA_SHOP"}, + {"owner": "&userName", "name": "STREAMS"}, + {"owner": "&userName", "name": "MOVIES"}, + {"owner": "&userName", "name": "ACTORS"} + ] + }' + ); + end; + / + + +-- Set that profile for this session +begin + dbms_cloud_ai.set_profile( + profile_name => '&profileName' + ); +end; +/ + +/** +Start asking questions! +Notice how the SQL language has been extended with new AI keywords +-- 1. chat - general AI chat +-- 2. runsql - [default] ask a question and get a structured result +-- 3. narrate - ask a question and get a conversational result +-- 4. showsql - SQL used to produce the result +-- 5. explainsql - explains the query and its processing +*/ +-- simple chat +select ai chat what happened to the new england patriots; + +-- use your data +select ai what are our total views; +select ai showsql what are our total views; + +-- more sophisticated +select ai what are our total streams broken out by genre; +select ai explainsql what are our total streams broken out by genre; + +select ai what are total streams by movie for tom hanks movies; + +/** +There are also api's for using Select AI +*/ +-- Ask another simple question +SELECT + DBMS_CLOUD_AI.GENERATE( + PROMPT => 'What is Tom Hanks best known for', + PROFILE_NAME => '&profileName', + ACTION => 'chat' + ) AS response +FROM dual; + +/** + what's great is you can now easily apply AI to your organization's data with a simple query +*/ +-- look at a humorous support chat +SELECT support_chat +FROM v_customer_support +WHERE support_chat_id = 1; + +/* +Let's summarize find out the sentiment of the support conversation. +A JSON document is a really good way to structure the prompt; the LLM can easily interpret the +task and data set to operate on. The following SQL query combines the task with the data set. +*/ +-- Here's the task and we'll apply it to the support chat. +SELECT JSON_OBJECT( + 'task' VALUE 'summarize the support chat in 3 sentences. also return the customer sentiment', + support_chat) AS prompt_details +FROM v_customer_support WHERE support_chat_id = 1; + +-- now apply GenAI in a query to get teh answer +WITH prompt_document AS ( + -- this json document + SELECT JSON_OBJECT( + 'task' VALUE 'summarize the support chat in 3 sentences. also return the customer sentiment', + support_chat) AS prompt_details + FROM v_customer_support WHERE support_chat_id = 1 +) +SELECT + DBMS_CLOUD_AI.GENERATE( + PROMPT => prompt_details, + PROFILE_NAME => '&profileName', + ACTION => 'chat' + ) AS response +FROM prompt_document; + +/* Create an EMAIL promotion to a customer. Recommend movies based on + those they previously watched AND movies that Moviestream wants to promote. + This is information the LLM knows nothing about - the prompt will augment the model + with customer data +*/ +WITH promoted_movie_list AS +( + -- movies we want to promote + SELECT + json_arrayagg(json_object( + 'title' value m.json_document.title , + 'year' value m.json_document.year) + ) as promoted_movie_list + FROM "movieCollection" m + WHERE m.json_document.studio like '%Amblin Entertainment%' +), +customer_latest_movies AS ( + -- movies the customer watched + SELECT + s.cust_id, + m.title, + m.year, + max(s.day_id) as day_id + FROM streams s, movies m, v_target_customers c + WHERE m.movie_id = s.movie_id + and c.customer_id = 1 + and c.cust_id = s.cust_id + GROUP BY s.cust_id, m.title, m.year + ORDER BY day_id desc + FETCH first 3 ROWS ONLY +), +customer_details AS ( + -- attributes about the customer + SELECT + m.cust_id, + c.customer_id, + c.first_name, + c.last_name, + c.age, + c.gender, + c.has_kids, + c.marital_status, + c.dog_owner, + max(day_id), + json_arrayagg(m.title) as recently_watched_movies + FROM v_target_customers c, customer_latest_movies m + WHERE + c.cust_id = m.cust_id + GROUP BY + m.cust_id, + c.customer_id, + first_name, + last_name, + age, + gender, + has_kids, + marital_status, + dog_owner +), +dataset AS ( + -- combine this into a json document + SELECT json_object(p.*, c.*) doc + FROM customer_details c, promoted_movie_list p +) +SELECT + -- generate the promotion! + DBMS_CLOUD_AI.GENERATE ( + prompt => 'Create a promotional email with a catchy subject line and convincing email text. Follow the task rules. ' || + '1. Recommend 3 movies from the promoted movie list that are most similar to movies in the recently watched movie list. ' || + ' Do not say that we are promoting these movies. For each move, say why you will love them.' || + '2. Use lots of fun emojis in the response. ' || + '3. Finish the email thanking them for being a customer and sign it "From The MovieStream Team" \n' + || doc, + profile_name => '&profileName', + action => 'chat' + ) AS email_promotion +FROM dataset; + + +