SQL Articles
Know how to get your data moving when the database says, "Talk SQL to me."
Articles From SQL
Filter Results
Cheat Sheet / Updated 04-25-2022
SQL is a popular and useful programming language. You can make SQL even more useful if you know the phases of SQL development, the criteria for normal forms, the data types used by SQL, a little bit about set and value functions, as well as some tips on how to filter tables with WHERE clauses.
View Cheat SheetCheat Sheet / Updated 01-27-2022
This Cheat Sheet consists of several helpful tables and lists, containing information that comes up repeatedly when working with structured query language (SQL). In one place, you can get a quick answer to a number of different questions that frequently arise during an SQL development effort.
View Cheat SheetArticle / Updated 01-18-2022
SQL gives you options for retrieving, analyzing, and displaying the information you need with the GROUP BY, HAVING, and ORDER BY clauses. Here are some examples of how you can use them. GROUP BY clauses Sometimes, rather than retrieving individual records, you want to know something about a group of records. The GROUP BY clause is the tool you need. Suppose you’re the sales manager of another location, and you want to look at the performance of your sales force. If you do a simple SELECT, such as the following query: SELECT InvoiceNo, SaleDate, Salesperson, TotalSale FROM SALES; This result gives you some idea of how well your salespeople are doing because so few total sales are involved. However, in real life, a company would have many more sales — and it wouldn’t be so easy to tell whether sales objectives were being met. To do the real analysis, you can combine the GROUP BY clause with one of the aggregate functions (also called set functions) to get a quantitative picture of sales performance. For example, you can see which salesperson is selling more of the profitable high-ticket items by using the average (AVG) function as follows: SELECT Salesperson, AVG(TotalSale) FROM SALES GROUP BY Salesperson; Running the query with a different database management system would retrieve the same result, but might appear a little different. The average value of Bennett’s sales is considerably higher than that of the other two salespeople. You compare total sales with a similar query: SELECT Salesperson, SUM(TotalSale) FROM SALES GROUP BY Salesperson; Bennett also has the highest total sales, which is consistent with having the highest average sales. HAVING clauses You can analyze the grouped data further by using the HAVING clause. The HAVING clause is a filter that acts similar to a WHERE clause, but on groups of rows rather than on individual rows. To illustrate the function of the HAVING clause, suppose the sales manager considers Bennett to be in a class by himself. His performance distorts the overall data for the other salespeople. (Aha — a curve-wrecker.) You can exclude Bennett’s sales from the grouped data by using a HAVING clause as follows: SELECT Salesperson, SUM(TotalSale) FROM SALES GROUP BY Salesperson HAVING Salesperson <>'Bennett'; Only rows where the salesperson is not Bennett are considered. ORDER BY clauses Use the ORDER BY clause to display the output table of a query in either ascending or descending alphabetical order. Whereas the GROUP BY clause gathers rows into groups and sorts the groups into alphabetical order, ORDER BY sorts individual rows. The ORDER BY clause must be the last clause that you specify in a query. If the query also contains a GROUP BY clause, the clause first arranges the output rows into groups. The ORDER BY clause then sorts the rows within each group. If you have no GROUP BY clause, then the statement considers the entire table as a group, and the ORDER BY clause sorts all its rows according to the column (or columns) that the ORDER BY clause specifies. To illustrate this point, consider the data in the SALES table. The SALES table contains columns for InvoiceNo, SaleDate, Salesperson, and TotalSale. If you use the following example, you see all the data in the SALES table — but in an arbitrary order: SELECT * FROM SALES ; In one implementation, this may be the order in which you inserted the rows in the table; in another implementation, the order may be that of the most recent updates. The order can also change unexpectedly if anyone physically reorganizes the database. That’s one reason it’s usually a good idea to specify the order in which you want the rows. You may, for example, want to see the rows in order by the SaleDate like this: SELECT * FROM SALES ORDER BY SaleDate ; This example returns all the rows in the SALES table in order by SaleDate. For rows with the same SaleDate, the default order depends on the implementation. You can, however, specify how to sort the rows that share the same SaleDate. You may want to see the sales for each SaleDate in order by InvoiceNo, as follows: SELECT * FROM SALES ORDER BY SaleDate, InvoiceNo ; This example first orders the sales by SaleDate; then for each SaleDate, it orders the sales by InvoiceNo. But don’t confuse that example with the following query: SELECT * FROM SALES ORDER BY InvoiceNo, SaleDate ; This query first orders the sales by INVOICE_NO. Then for each different InvoiceNo, the query orders the sales by SaleDate. This probably won’t yield the result you want, because it’s unlikely that multiple sale dates will exist for a single invoice number. The following query is another example of how SQL can return data: SELECT * FROM SALES ORDER BY Salesperson, SaleDate ; This example first orders by Salesperson and then by SaleDate. After you look at the data in that order, you may want to invert it, as follows: SELECT * FROM SALES ORDER BY SaleDate, Salesperson ; This example orders the rows first by SaleDate and then by Salesperson. All these ordering examples are in ascending (ASC) order, which is the default sort order. The last SELECT shows earlier sales first — and, within a given date, shows sales for ‘Adams’ before ‘Baker’. If you prefer descending (DESC) order, you can specify this order for one or more of the order columns, as follows: SELECT * FROM SALES ORDER BY SaleDate DESC, Salesperson ASC ; This example specifies a descending order for sale dates, showing the more recent sales first, and an ascending order for salespeople, putting them in alphabetical order. That should give you a better picture of how Bennett’s performance stacks up against that of the other salespeople.
View ArticleArticle / Updated 01-14-2022
After you create a database in SQL, the next step is to fill it with data. The next step after that is to wait around until there's a need for some particular bit of information contained somewhere in that data, like a needle in a haystack. When the time comes and you want to find that needle, you can use SQL's Data Manipulation Language (DML) to perform a virtual needle extraction. Sometimes the data you want is not stored in any single table in your database, but instead pieces of it are scattered across multiple tables. SQL offers several methods of gathering such far-flung data and presenting it to you integrated together in a nice compact result set, some of which are described here: Relational operators have the ability to combine information from multiple sources in a variety of ways. For example, the UNION operator will return all the rows that appear in either of two compatible tables. In contrast, the INTERSECT operator will return only the rows that appear in both of two compatible tables. When you use the EXCEPT operator, all the rows from one table will be returned, except for rows that match rows in the second table. In addition, a wide variety of join operators will enable you to fine-tune your retrievals, pulling just the data you want from whichever tables it might reside in. Nested queries allow you to retrieve data from multiple tables. These are queries on one table that include a subquery on a different table. The subquery is executed first and its result is then passed to the main query to provide a result that contains information from both. Recursive queries have the rather amazing ability to call themselves. This ability can be a major time saver, enabling a search tree to be traversed in a lot less time that an exhaustive search would take. Bill of Materials databases are places where recursive queries can deliver major performance gains.
View ArticleArticle / Updated 01-14-2022
There are three sources of modification anomalies in SQL These are defined as first, second, and third normal forms (1NF, 2NF, 3NF). These normal forms act as remedies to modification anomalies. First normal form To be in first normal form (1NF), a table must have the following qualities: The table is two-dimensional with rows and columns. Each row contains data that pertains to some thing or portion of a thing. Each column contains data for a single attribute of the thing it’s describing. Each cell (intersection of a row and a column) of the table must have only a single value. Entries in any column must all be of the same kind. If, for example, the entry in one row of a column contains an employee name, all the other rows must contain employee names in that column, too. Each column must have a unique name. No two rows may be identical (that is, each row must be unique). The order of the columns and the order of the rows are not significant. A table (relation) in first normal form is immune to some kinds of modification anomalies but is still subject to others. The SALES table is in first normal form, and the table is subject to deletion and insertion anomalies. First normal form may prove useful in some applications but unreliable in others. Second normal form To appreciate second normal form, you must understand the idea of functional dependency. A functional dependency is a relationship between or among attributes. One attribute is functionally dependent on another if the value of the second attribute determines the value of the first attribute. If you know the value of the second attribute, you can determine the value of the first attribute. Suppose, for example, that a table has attributes (columns) StandardCharge, NumberOfTests, and TotalCharge that relate through the following equation: TotalCharge = StandardCharge * NumberOfTests TotalCharge is functionally dependent on both StandardCharge and NumberOfTests. If you know the values of StandardCharge and NumberOfTests, you can determine the value of TotalCharge. Every table in first normal form must have a unique primary key. That key may consist of one or more than one column. A key consisting of more than one column is called a composite key. To be in second normal form (2NF), all non-key attributes must depend on the entire key. Thus, every relation that is in 1NF with a single attribute key is automatically in second normal form. If a relation has a composite key, all non-key attributes must depend on all components of the key. If you have a table where some non-key attributes don’t depend on all components of the key, break the table up into two or more tables so that — in each of the new tables — all non-key attributes depend on all components of the primary key. Sound confusing? Look at an example to clarify matters. Consider the SALES table. Instead of recording only a single purchase for each customer, you add a row every time a customer buys an item for the first time. An additional difference is that charter customers (those with Customer_ID values of 1001 to 1007) get a discount off the normal price. Customer_ID does not uniquely identify a row. In two rows, Customer_ID is 1001. In two other rows, Customer_ID is 1010. The combination of the Customer_ID column and the Product column uniquely identifies a row. These two columns together are a composite key. If not for the fact that some customers qualify for a discount and others don’t, the table wouldn’t be in second normal form, because Price (a non-key attribute) would depend only on part of the key (Product). Because some customers do qualify for a discount, Price depends on both CustomerID and Product, and the table is in second normal form. Third normal form Tables in second normal form are especially vulnerable to some types of modification anomalies — in particular, those that come from transitive dependencies. A transitive dependency occurs when one attribute depends on a second attribute, which depends on a third attribute. Deletions in a table with such a dependency can cause unwanted information loss. A relation in third normal form is a relation in second normal form with no transitive dependencies. Look again at the SALES table, which you know is in first normal form. As long as you constrain entries to permit only one row for each Customer_ID, you have a single-attribute primary key, and the table is in second normal form. However, the table is still subject to anomalies. What if customer 1010 is unhappy with the chlorine bleach, for example, and returns the item for a refund? You want to remove the third row from the table, which records the fact that customer 1010 bought chlorine bleach. You have a problem: If you remove that row, you also lose the fact that chlorine bleach has a price of $4. This situation is an example of a transitive dependency. Price depends on Product, which, in turn, depends on the primary key Customer_ID. Breaking the SALES table into two tables solves the transitive dependency problem. The two tables make up a database that’s in third normal form.
View ArticleArticle / Updated 01-14-2022
Every column contains one value for each row of a table. SQL statements often refer to such values. A fully qualified column reference consists of the table name, a period, and then the column name (for example, PRICING.Product). Consider the following statement: SELECT PRICING.Cost FROM PRICING WHERE PRICING.Product = 'F-35' ; Here PRICING.Product is a column reference. This reference contains the value ‘F-35’. PRICING.Cost is also a column reference, but you don’t know its value until the preceding SELECT statement executes. Because it only makes sense to reference columns in the current table, you don’t generally need to use fully qualified column references. The following statement, for example, is equivalent to the previous one: SELECT Cost FROM PRICING WHERE Product = 'F-35' ; Sometimes you may be dealing with more than one table — say, when two tables in a database contain one or more columns with the same name. In such a case, you must fully qualify column references for those columns to guarantee that you get the column you want. For example, suppose that your company maintains facilities in both Kingston and Jefferson, and you maintain separate employee records for each site. You name the Kingston employee table EMP_KINGSTON, and you name the Jefferson employee table EMP_JEFFERSON. You want a list of employees who work at both sites, so you need to find the employees whose names appear in both tables. The following SELECT statement gives you what you want: SELECT EMP_KINGSTON.FirstName, EMP_KINGSTON.LastName FROM EMP_KINGSTON, EMP_JEFFERSON WHERE EMP_KINGSTON.EmpID = EMP_JEFFERSON.EmpID ; Because each employee’s ID number is unique and remains the same regardless of the work site, you can use this ID as a link between the two tables. This retrieval returns only the names of employees who appear in both tables.
View ArticleArticle / Updated 01-14-2022
Referential integrity involves maintaining consistency in a multitable SQL database. You can lose integrity by adding a row to a child table that doesn’t have a corresponding row in the child’s parent table. You can cause similar problems by deleting a row from a parent table if rows corresponding to that row exist in a child table. Suppose your business has a CUSTOMER table that keeps track of all your customers and a SALES table that records all sales transactions. You don’t want to add a row to SALES until after you enter the customer making the purchase into the CUSTOMER table. You also don’t want to delete a customer from the CUSTOMER table if that customer made purchases that exist in the SALES table. Before you perform an insertion or a deletion, you may want to check the candidate row to make sure that inserting or deleting that row doesn’t cause integrity problems. The MATCH predicate can perform such a check. Say you have a CUSTOMER table and a SALES table. CustomerID is the primary key of the CUSTOMER table and acts as a foreign key in the SALES table. Every row in the CUSTOMER table must have a unique CustomerID that isn’t null. CustomerID isn’t unique in the SALES table, because repeat customers buy more than once. This situation is fine; it doesn’t threaten integrity because CustomerID is a foreign key rather than a primary key in that table. Seemingly, CustomerID can be null in the SALES table, because someone can walk in off the street, buy something, and walk out before you get a chance to enter his or her name and address into the CUSTOMER table. This situation can create trouble — a row in the child table with no corresponding row in the parent table. To overcome this problem, you can create a generic customer in the CUSTOMER table and assign all anonymous sales to that customer. Say that a customer steps up to the cash register and claims that she bought an F-35 Strike Fighter on December 18, 2012. Although she has lost her receipt, she now wants to return the plane because it shows up like an aircraft carrier on opponents’ radar screens. You can verify whether she bought an F-35 by searching your SALES database for a match. First, you must retrieve her CustomerID into the variable vcustid; then you can use the following syntax: ... WHERE (:vcustid, 'F-35', '2017-12-18') MATCH (SELECT CustomerID, ProductID, SaleDate FROM SALES) If the MATCH predicate returns a True value, the database contains a sale of the F-35 on December 18, 2017, to this client’s CustomerID. Take back the defective product and refund the customer’s money. (Note: If any values in the first argument of the MATCH predicate are null, a True value always returns.) SQL’s developers added the MATCH predicate and the UNIQUE predicate for the same reason — they provide a way to explicitly perform the tests defined for the implicit referential integrity (RI) and UNIQUE constraints. The general form of the MATCH predicate is as follows: Row_valueMATCH [UNIQUE] [SIMPLE| PARTIAL | FULL ] Subquery The UNIQUE, SIMPLE, PARTIAL, and FULL options relate to rules that come into play if the row value expression R has one or more columns that are null. The rules for the MATCH predicate are a copy of corresponding referential integrity rules.
View ArticleArticle / Updated 01-14-2022
Within the WHERE clause lies many possibilities for modifying your SQL statement. Among these possibilities are the EXISTS, UNIQUE, DISTINCT, and OVERLAPS predicates. Here are some examples of how to use these in your SQL statements. EXISTS You can use the EXISTS predicate in conjunction with a subquery to determine whether the subquery returns any rows. If the subquery returns at least one row, that result satisfies the EXISTS condition, and the outer query executes. Consider the following example: SELECT FirstName, LastName FROM CUSTOMER WHERE EXISTS (SELECT DISTINCT CustomerID FROM SALES WHERE SALES.CustomerID = CUSTOMER.CustomerID); Here the SALES table contains all of your company’s sales transactions. The table includes the CustomerID of the customer who makes each purchase, as well as other pertinent information. The CUSTOMER table contains each customer’s first and last names, but no information about specific transactions. The subquery in the preceding example returns a row for every customer who has made at least one purchase. The outer query returns the first and last names of the customers who made the purchases that the SALES table records. EXISTS is equivalent to a comparison of COUNT with zero, as the following query shows: SELECT FirstName, LastName FROM CUSTOMER WHERE 0 <> (SELECT COUNT(*) FROM SALES WHERE SALES.CustomerID = CUSTOMER.CustomerID); For every row in the SALES table that contains a CustomerID that’s equal to a CustomerID in the CUSTOMER table, this statement displays the FirstName and LastName columns in the CUSTOMER table. For every sale in the SALES table, therefore, the statement displays the name of the customer who made the purchase. UNIQUE As you do with the EXISTS predicate, you use the UNIQUE predicate with a subquery. Although the EXISTS predicate evaluates to True only if the subquery returns at least one row, the UNIQUE predicate evaluates to True only if no two rows returned by the subquery are identical. In other words, the UNIQUE predicate evaluates to True only if all the rows that its subquery returns are unique. Consider the following example: SELECT FirstName, LastName FROM CUSTOMER WHERE UNIQUE (SELECT CustomerID FROM SALES WHERE SALES.CustomerID = CUSTOMER.CustomerID); This statement retrieves the names of all new customers for whom the SALES table records only one sale. Because a null value is an unknown value, two null values aren’t considered equal to each other; when the UNIQUE keyword is applied to a result table that contains only two null rows, the UNIQUE predicate evaluates to True. DISTINCT The DISTINCT predicate is similar to the UNIQUE predicate, except in the way it treats nulls. If all the values in a result table are UNIQUE, then they’re also DISTINCT from each other. However, unlike the result for the UNIQUE predicate, if the DISTINCT keyword is applied to a result table that contains only two null rows, the DISTINCT predicate evaluates to False. Two null values are not considered distinct from each other, while at the same time they are considered to be unique. This strange situation seems contradictory, but there’s a reason for it. In some situations, you may want to treat two null values as different from each other — in which case, use the UNIQUE predicate. When you want to treat the two nulls as if they’re the same, use the DISTINCT predicate. OVERLAPS You use the OVERLAPS predicate to determine whether two time intervals overlap each other. This predicate is useful for avoiding scheduling conflicts. If the two intervals overlap, the predicate returns a True value. If they don’t overlap, the predicate returns a False value. You can specify an interval in two ways: either as a start time and an end time or as a start time and a duration. Here are some examples: (TIME '2:55:00', INTERVAL '1' HOUR) OVERLAPS (TIME '3:30:00', INTERVAL '2' HOUR) This first example returns a True because 3:30 is less than one hour after 2:55. (TIME '9:00:00', TIME '9:30:00') OVERLAPS (TIME '9:29:00', TIME '9:31:00') This example returns a True because you have a one-minute overlap between the two intervals. (TIME '9:00:00', TIME '10:00:00') OVERLAPS (TIME '10:15:00', INTERVAL '3' HOUR) This example returns a False because the two intervals don’t overlap. (TIME '9:00:00', TIME '9:30:00') OVERLAPS (TIME '9:30:00', TIME '9:35:00') This example returns a False because even though the two intervals are contiguous, they don’t overlap.
View ArticleArticle / Updated 01-14-2022
The first step to designing any database in SQL is to identify what to include and what not to include. The next steps involve deciding how the included items relate to each other and then setting up tables accordingly. To design a database in SQL, follow these basic steps: Decide what objects you want to include in your database. Determine which of these objects should be tables and which should be columns within those tables. Define tables based on how you need to organize the objects. Optionally, you may want to designate a table column or a combination of columns as a key. Step 1: Define objects The first step in designing a database is deciding which aspects of the system are important enough to include in the model. Treat each aspect as an object and create a list of all the objects you can think of. At this stage, don’t try to decide how these objects relate to each other. Just try to list them all. When you have a reasonably complete set of objects, move on to the next step: deciding how these objects relate to each other. Some of the objects are major entities that are crucial to giving you the results you want. Other objects are subsidiary to those major entities. Ultimately you may decide that some objects don’t belong in the model at all. Step 2: Identify tables and columns Major entities translate into database tables. Each major entity has a set of attributes — the table columns. Many business databases, for example, have a CUSTOMER table that keeps track of customers’ names, addresses, and other permanent information. Each attribute of a customer — such as name, street, city, state, zip code, phone number, and e-mail address — becomes a column (and a column heading) in the CUSTOMER table. If you’re hoping to find a set of rules to help you identify which objects should be tables and which of the attributes in the system belong to which tables, think again: You may have some reasons for assigning a particular attribute to one table and other reasons for assigning the same attribute to another table. You must base your judgment on two goals: The information you want to get from the database How you want to use that information When deciding how to structure database tables, involve future users of the database as well as the people who will make decisions based on database information. If you come up with what you think is a reasonable structure, but it isn’t consistent with the way that people will use the information, your system will be frustrating to use at best — and could even produce wrong information, which is even worse. Take a look at an example. Suppose you just established VetLab, a clinical microbiology laboratory that tests biological specimens sent in by veterinarians. You want to track several things, including the following: Clients Tests that you perform Employees Orders Results Each of these entities has associated attributes. Each client has a name, an address, and other contact information. Each test has a name and a standard charge. Each employee has contact information as well as a job classification and pay rate. For each order, you need to know who ordered it, when it was ordered, and what test was ordered. For each test result, you need to know the outcome of the test, whether the results were preliminary or final, and the test order number. Step 3: Define tables Now you want to define a table for each entity and a column for each attribute. Table Columns CLIENT Client Name Address 1 Address 2 City State Postal Code Phone Fax Contact Person TESTS Test Name Standard Charge EMPLOYEE Employee Name Address 1 Address 2 City State Postal Code Home Phone Office Extension Hire Date Job Classification Hourly/Salary/Commission ORDERS Order Number Client Name Test Ordered Responsible Salesperson Order Date RESULTS Result Number Order Number Result Date Reported Preliminary/Final You can create the tables defined here by using either a rapid application development (RAD) tool or by using SQL’s Data Definition Language (DDL), as shown in the following code: CREATE TABLE CLIENT ( ClientName CHAR (30) NOT NULL, Address1 CHAR (30), Address2 CHAR (30), City CHAR (25), State CHAR (2), PostalCode CHAR (10), Phone CHAR (13), Fax CHAR (13), ContactPerson CHAR (30) ) ; CREATE TABLE TESTS ( TestName CHAR (30) NOT NULL, StandardCharge CHAR (30) ) ; CREATE TABLE EMPLOYEE ( EmployeeName CHAR (30) NOT NULL, Address1 CHAR (30), Address2 CHAR (30), City CHAR (25), State CHAR (2), PostalCode CHAR (10), HomePhone CHAR (13), OfficeExtension CHAR (4), HireDate DATE, JobClassification CHAR (10), HourSalComm CHAR (1) ) ; CREATE TABLE ORDERS ( OrderNumber INTEGER NOT NULL, ClientName CHAR (30), TestOrdered CHAR (30), Salesperson CHAR (30), OrderDate DATE ) ; CREATE TABLE RESULTS ( ResultNumber INTEGER NOT NULL, OrderNumber INTEGER, Result CHAR(50), DateReported DATE, PrelimFinal CHAR (1) ) ; These tables relate to each other by the attributes (columns) that they share, as the following list describes: The CLIENT table links to the ORDERS table by the ClientName column. The TESTS table links to the ORDERS table by the TestName (TestOrdered) column. The EMPLOYEE table links to the ORDERS table by the EmployeeName (Salesperson) column. The RESULTS table links to the ORDERS table by the OrderNumber column. If you want a table to serve as an integral part of a relational database, link that table to at least one other table in the database, using a common column. The links illustrate four different one-to-many relationships. The diamond in the middle of each relationship shows the maximum cardinality of each end of the relationship. The number 1 denotes the “one” side of the relationship, and N denotes the “many” side. One client can make many orders, but each order is made by one, and only one, client. Each test can appear on many orders, but each order calls for one, and only one, test. Each order is taken by one, and only one, employee (or salesperson), but each salesperson can take multiple orders. Each order can produce several preliminary test results and a final result, but each result is associated with one, and only one, order. The attribute that links one table to another can have a different name in each table. Both attributes must, however, have matching data types.
View ArticleArticle / Updated 01-14-2022
Whether you’re working with Access or a full-featured enterprise-level DBMS — like Microsoft SQL Server, Oracle, or IBM DB2 — to create a table with SQL, you must enter the same information that you’d enter if you created the table with a RAD tool. The difference is that the RAD tool helps you by providing a visual interface — in the form of a table-creation dialog box (or some similar data-entry skeleton) — and by preventing you from entering invalid field names, types, or sizes. SQL doesn’t give you as much help. You must know what you’re doing at the onset; figuring things out along the way can lead to less-than-desirable database results. You must enter the entire CREATE TABLE statement before SQL even looks at it, let alone gives you any indication of whether you made errors in the statement. In ISO/IEC standard SQL, the statement that creates a proposal-tracking table uses the following syntax: CREATE TABLE POWERSQL ( ProposalNumber INTEGER PRIMARY KEY, FirstName CHAR (15), LastName CHAR (20), Address CHAR (30), City CHAR (25), StateProvince CHAR (2), PostalCode CHAR (10), Country CHAR (30), Phone CHAR (14), HowKnown CHAR (30), Proposal CHAR (50), BusinessOrCharity CHAR (1) ); The information in the SQL statement is essentially the same information you enter using Access’s graphical user interface. The nice thing about SQL is that the language is universal. The same standard syntax works regardless of what standard-compliant DBMS product you use. In Access 2016, creating database objects such as tables is a little more complicated. You can’t just type a CREATE statement into the SQL View Object tab. That’s because the SQL View Object tab is available only as a query tool; you have to take a few extra actions to inform Access that you’re about to enter a data-definition query rather than a query that requests information from the database. A further complication: Because table creation is an action that could possibly compromise database security, it’s disallowed by default. You must tell Access that this is a trusted database before it will accept a data-definition query. Click the Create tab on the Ribbon to display the icons for creation functionality. Click Query Design in the Queries section. This displays the Show Table dialog box, which at this point contains several system tables along with POWER. Select POWER and click the Add button. As you’ve seen in the previous example, a picture of the POWER table and its attributes appears in the upper half of the work area. Click the Close button on the Show Table dialog box. Click the Home tab and then pull down the View menu at the left end of the Ribbon and then choose SQL View from the menu. As in the previous example, Access has “helped” you by putting SELECT FROM POWER in the SQL editor. This time you don’t want the help. Delete SELECT FROM POWER and (in its place) enter the data-definition query given earlier, as follows: CREATE TABLE POWERSQL ( ProposalNumber INTEGER PRIMARY KEY, FirstName CHAR (15), LastName CHAR (20), Address CHAR (30), City CHAR (25), StateProvince CHAR (2), PostalCode CHAR (10), Country CHAR (30), Phone CHAR (14), HowKnown CHAR (30), Proposal CHAR (50), BusinOrCharity CHAR (1) ); After clicking the Design tab of the Ribbon, click the red exclamation point Run icon. Doing so runs the query, which creates the POWERSQL table. You should see POWERSQL listed under All Access Objects in the column at the left edge of the window. In which case, you’re golden. Or you may not see the table in the All Access Objects list. In that case, read (and slog) on. Access 2016 goes to great lengths to protect you from malicious hackers and from your own inadvertent mistakes. Because running a data-definition query is potentially dangerous to the database, Access has a default that prevents the query from running. If this has happened to you, POWERSQL won’t appear in the column at the left of the window, because the query won’t have been executed. Instead, the Message Bar may appear below the Ribbon, with this terse message: Security Warning: Certain content in the database has been disabled. If you see this message, move on to the next steps. Click the File tab and, from the menu of the left edge, choose Options. The Access Options dialog box appears. Select Trust Center from the Access Options dialog box. Click the Trust Center Settings button when it appears. Select Message Bar from the menu on the left and then specify Show the Message Bar by clicking its option button if it isn’t already selected. Click your way back to the place where you can execute the data-definition query that creates the POWERSQL table. Execute the query. Becoming proficient in SQL has long-term payoffs because it will be around for a long time. The effort you put into becoming an expert in a particular development tool is likely to yield a lower return on investment. No matter how wonderful the latest RAD tool may be, it will be superseded by newer technology within three to five years. If you can recover your investment in the tool in that time, great! Use it. If not, you may be wise to stick with the tried and true. Train your people in SQL, and your training investment will pay dividends over a much longer period.
View Article