text:
All local phone numbers should be preceded with a (904) unless otherwise listed.
All addresses are in St. Augustine unless otherwise specified.
Friday, Aug. 31
Artist talk and exhibit opening: The Crisp-Ellert Art Museum, on the Flagler College campus, presents an upcoming exhibition and project organized by Portland-based artist Harrell Fletcher. "Before and After 1565" is a participatory examination of St. Augustine's Native American history collaboratively produced by members of the St. Augustine community and Fletcher. An artist talk with students Tara Stephens and Eileen Pagan will begin at 4 p.m.; with an opening reception from 5 to 9 p.m.; and a trolley tours of Native American and Indigenous sites from 6 to 9 p.m. The museum is at 48 Sevilla St., downtown St. Augustine. Go to www.flagler.edu/crispellert or call 826-8530.
St. Augustine Lighthouse sunset & moonrise: See the full moon during a Sunset Moonrise event at the St. Augustine Lighthouse, 81 Lighthouse Ave. This special event includes a champagne toast provided by San Sebastian Winery, light hors d'oeuvre's provided by The Reef, and an informative overview of the St. Augustine Light Station. The fee is $25 for non-museum members ($20 for members). Reservations are required and space is limited. Call 829-0745.
Stars Flashin' with Passion for Fashion: Fashion designers will compete to become the top fashion designer during Stars Flashin' with Passion for Fashion. Models are local youth who are learning self confidence and poise. Tickets are $10 in advance, $15 at the door. The show will begin at 7 p.m. in the Pioneer Barn at Old Florida Museum Fort Matanzas, 259 San Marco Ave. Call 824-8876 or go to www.FortMatanzas.com.
Dollar Double IMAX Feature: To celebrate the launch of IMAX classic documentaries "Deep Sea 3D" and "Galapagos 3D," guests who purchase a ticket to an IMAX documentary film beginning at 5 p.m. on Fridays through the last show of the weekend will get admission to a second documentary film for just $1. "Deep Sea 3D" opens Aug. 31, and the Dollar Double Feature will run through Monday, Sept. 3. "Galapagos 3D" opens Sept. 14 and the Dollar Double Feature Weekend deal will run through Sept. 16. Go to www.WorldGolfIMAX.com.
San Sebastian Winery live music: The Cellar Upstairs Wine, Jazz & Blues Bar is located on the rooftop of the winery, 157 King St. Live music by Pili Pili will be from 7 to 11 p.m. today; with SMG from 2 to 5 p.m. Sept. 1, followed by Mojo Roux from 7 to 11 p.m.; and Vinny Jacobs from 2 to 5 p.m. Sunday, Sept. 2. Call 826-1594 or go to www.sansebastianwinery.com.
Ann O'Malley's live music: TJ Ward will perform from 8:30 p.m. to 12:30 a.m. in Ann O'Malley's Deli & Pub, 23 Orange St., downtown St. Augustine. On Sept. 1, Chelsea Saddler will perform from 8:30 p.m. to 12:30 a.m. Call 825-4040 or go to www.annomalleys.com.
St. Augustine Historic Walking Tours: A pirate pub crawl begins at 7 p.m. each Friday and Saturday for $17 per person. In addition, a St. Augustine Beer Experience is offered at 5 p.m. every Wednesday and Friday for $52 per person and includes 16-19 beer samples and appetizers. St. Augustine Historic Walking tours also offers family-friend tours include Pirates, Plunder and Parlay at 4:30 p.m. each Friday and Saturday, and St, Augustine Ghosts & Legends at 8 p.m. each Friday and Saturday. For details, go to www.StAugustine
HistoricTours.com or call 392-7137.
Jazz music: The Groov Band will perform from 7 to 10 p.m. each Thursday and Sunday at Sara's Crepe Cafe, 100 St. George St. Call 810-5800. Go to www.thegroovband.com to learn more about the band.
E.T. Swing's the Thing: Jazz and swing music will perform from 5 to 8 p.m. by E.T. Swing's the Thing in Holiday Isle Oceanfront Resort, 860 A1A Beach Blvd. Call Eddie Trester at 471-8897.
Schooner Freedom sailing trips: Day sails are available at 12:15 p.m. on the Schooner Freedom, departing from the St. Augustine Municipal Marina, 111 Avenida Menendez. Sunset sails are offered at 6:15 p.m. on certain days. For reservations, call 810-1010 or go to www.schoonerfreedom.com.
Dancing with Victoria: Ballroom and Latin social dances are held the second and fourth Friday of each month from 7:30 to 9:30 p.m. at Dancing with Victoria, 4420 U.S. 1 South. Music will be played for all styles of dancing - swing, foxtrot, tango, salsa, merengue, cha cha, disco, freestyle and more. Cost is $10 per person. Soda and wine are available. Call 540-0225 or go to www.chachavictoria.com.
Tini Martini Bar music: Live music will be available from 5:30 to 9:30 p.m. in the Tini Martini Bar, 24 Avenida Menendez, at the Casablanca Inn on the bayfront. Call 829-6510.
Acoustic guitar music: Local musician Dan Pillen will play acoustic guitar from 7 to 9 p.m. each Friday at Present Moment Cafe, 224 W. King St. Go to thepresentmomentcafe.com or call 827-4499.
Old Jail ghost hunt: Every Friday and Saturday night, paranormal seekers lead late-night investigations at St. Augustine's Old Jail, 167 San Marco Ave. Tours begin at 10:45 p.m. Call 829-3800 or go to www.trustedtours.com/staugustine.
Ripley's seasonal trolley tours: Ripley's Attractions offers new seasonal tours this summer. The Sunset Tour will be from 6 to 7:30 p.m. daily throughout the summer. Guests will enjoy historic narration interspersed with fun summertime. For those who love the paranormal, Team R.I.P. (Ripley's Investigators of the Paranormal) has exclusive investigations beginning at 8:15 p.m. every Friday and Saturday to a pair of isolated and haunted locations - The Fountain of Youth and the old Fairbanks Plantation (site of the forthcoming St. Augustine Haunted History Museum) for 90-minute investigations. Call 829-6545 or go to www.ripleys.com/redtrains.
Violin and jam sessions: Group violin lessons and jam sessions will begin at 5 p.m. Thursdays and Fridays with award-winning musician/instructor Allen Hood. All ages are welcome. Call 829-9829 or 824-1649 for more information.
Saturday, Sept. 1
Sunset Celebration at Vilano Beach: The Sunset Celebration is an event from 3 to 7 p.m. the first Saturday of each month at Vilano Beach Town Center which includes artist performers, local arts and crafts, and a view of the sunset. Dine on food samples from local businesses along Vilano Road and see why Vilano Beach is the best-kept hidden treasure in the county. Floating docks near the pier allow for waterway transport from the mainland to the island - just as in the early Henry Flagler days. Admission is free. Go to www.vilanobeachfl.com or call 540-0402.
Comedy show: Comedian Dean Napolitano will be on stage at 8:30 p.m. in Jackie Knight's Comedy Club at Gypsy Cab Corner Bar, 828 Anastasia Blvd. Comedian Chris Gay will open the show. Tickets are $12 per person. For reservations, call 461-8843 or go to www.thegypsycomedyclub.com.
VFW dinner show: The Bryan Tutten Memorial VFW Post 2391 and its Ladies Auxiliary will host "Yes You Can Dance To That" dinner and show featuring the "VFW Singers." Tickets are $15 per person, on sale at the VFW Post, 6184 U.S. 1 South. The dinner will be from 5 to 7 p.m., followed by the show. Proceeds will go to breast cancer awareness. Call 797-5267.
Elks Doo Wop: The Elks Lodge No. 829 will host the annual Doo Wop Dance at the Elks Lodge, 420 A1A South, featuring the "Knights to Remember." Elks members are asked to contact Elizabeth West at 461-4169 for tickets.
Platters, Coasters & Temptations Salute: Enjoy an evening of performances by former lead singer of the Platters, Myles Savage. The show will include classic songs such as "Only You," "Smoke Gets in Your Eyes," "My Girl," "Up On the Roof" and many more. Two concerts will be offered, at 3 and 7 p.m. in the Pioneer Barn at Old Florida Museum Fort Matanzas, 259 San Marco Ave. Tickets are $20. Call 824-8876 or go to www.FortMatanzas.com.
International Vulture Awareness Day: The Alligator Farm will celebrate International Vulture Awareness Day (www.vultureday.org/2012) with bird presentations, vulture nests for children to build, and vulture snacks for the public to free the birds. For details, go to www.alligatorfarm.com.
Kayak ecotour: A kayak tour from Faver-Dykes State Park, 1000 Faver-Dykes Road, from U.S. 1 South, will be from 9 a.m. to noon with Ripple Effect Ecotours. Cost is $55 and include kayaking equipment and admission to the park. Another tours is set at the same time on Sept. 30. Call 347-1565 or reserve online at www.rippleeffectecotours.com.
Free yoga: The Yoga Room, 2075 A1A South, in Portman Plaza will hold free yoga classes during National Yoga Month. Grand opening festivities will be from 5:30 to 7:30 p.m. Sept. 7 in the new location. Free classes will be from Sept. 10 through Sept. 15. Spaces are limited and pre registration is required. Go to www.staugustineyogaroom.com.
Labor Day Weekend boat trip: See St. Augustine in a new light on this 1.5 hour dolphin and nature boat trip. Explore the waters looking for marine life such as dolphins, beautiful wading birds and even a rare manatee. A Coast Guard certified captain and interpretive naturalist will lead the tour. Small groups up to six passengers will be offered by St. Augustine Eco Tours, departing from the St. Augustine Municipal Marina, 111 Avenida Menendez. Several departure times are schedule throughout the day. Cost is $35 per passenger. For reservations, call 377-7245 or go to www.staugustineecotours.com.
Meet and greet: The Friends of Alpine Park group will hold the first "Meet & Greet" event from 9 to 10 a.m. at Alpine Grove Park, 2060 State Road 13. The group will gather on the front porch of the Bennett farmhouse on the park grounds facing the St. Johns River. The morning will begin with citrus refreshments, and a short informative overview of the newly formed group and their goals. Park Naturalist Beverly Fleming will conduct a historical "chat" session on the conception of the park in 1999 and the activities since then and up to today. Call 522-1573 or email firstname.lastname@example.com.
Historic pub tour: Visit favorite bars and taverns with St. Augustine Historic Walking Tours. Guests will be offered premium, craft and local beer, sangria, wine, soda or coffee. Participants will learn about drinking customs, history of Saint Augustine and even the history of each pub. Each ticket entitles guests to one pint at each of the four pubs. For details, go to www.StAugustineHistoricTours.com or call 392-7137.
San Sebastian Winery live music: The Cellar Upstairs Wine, Jazz & Blues Bar is located on the rooftop of the winery, 157 King St. Live music by SMG from 2 to 5 p.m. Sept. 1, followed by Mojo Roux from 7 to 11 p.m.; and Vinny Jacobs from 2 to 5 p.m. Sunday, Sept. 2. Call 826-1594 or go to www.sansebastianwinery.com.
The St. Augustine Flea Market: Fresh produce and a U-pick hydroponics farm is offered every Saturday and Sunday at The St. Augustine Flea Market, 2495 State Road 207. Hours are 8 a.m. to 4 p.m. both days, with free parking and admission. The market offers more than 200 booths. Call 824-4210 or go to staugustinefleamarket.com.
Live music: Maja Gitana, a duo performing vocals, guitar, and violin, will play from 7 to 10 p.m. each Friday and Saturday at Sara's Crepe Cafe, 100 St. George St. Gypsy, Russian, Hungarian, Italian, French, and American music is played. Call 810-5800.
Old City Farmers' market: Find fresh produce, plants, bread, cheese, handmade products, fine art and crafts from 8:30 a.m. to 12:30 p.m. at the St. Augustine Amphitheatre, just south of the lighthouse. Also at the market, take art classes, hear live bluegrass music, and eat breakfast or lunch on site. Free parking and admission.
Cannon firing at Castillo: Every Saturday and Sunday, rangers and Garrison volunteers will demonstrate the weapons and relate the experiences of the colonial Spanish soldier of 1740s St. Augustine. Historic weapons demonstrations will be presented at 10:30 and 11:30 a.m., and 1:30, 2:30 and 3:30 p.m. Firing times are subject to change depending on weather conditions and staff availability. Fort hours are 8:45 a.m. to 5 p.m. daily. The Castillo de San Marcos is on the water on Avenida Menendez in downtown St. Augustine. Admission is $7 for adults, with free admission for children 14 and younger when accompanied by an adult. Go to www.nps.gov/casa or call 829-6506, ext. 227.
Nature movies at GTM Reserve: Every Saturday and Sunday, the GTM Reserve features free nature films at 10 a.m. and 1 p.m. in the Environmental Education Center, 500 Guana River Road, Ponte Vedra Beach. There is no cost to see the movie. Cost to tour the center is $2 or adults, $1 for children ages 10 to 17, and free for ages 9 and younger. Call 823-4500.
Paranormal experience: A new type of ghost experience, by 2ghouls Paranormal, is offered each week by owners Brandy Klopp and Tina Verduzco. History, folklore and positive energy are combined to create a recipe for taking the paranoid out of the paranormal. The Victorian-style experience includes parlor games. Tours depart from Alexander Homestead, 14 Sevilla St. Cost is $20 per person. For reservations, go to www.2ghouls.com or call 671-5010.
Sunday, Sept. 2
Lincolnville market: Fresh produce, handmade goods, arts and crafts and live music will be offered from 11 a.m. to 3 p.m. at the Lincolnville Market, on the fields next to the Willie Gallimore Center, 399 Riberia St. Vendors offer prepared foods, fresh produce, handmade arts, crafts, jewelry, baked goods, coffee and more. Parking is free.
Play Pétanque (boules): Similar to the Italian "bocce," the game of Pétanque is simple, relaxing, fun, and a way to enjoy time outside with friends. Pétanque is played in St. Augustine's sister city in Spain, and the St. Augustine's Pétanqueclub, Boules de Leon, meets from 1 to 4 p.m. each Sunday at Lighthouse park, near the St. Augustine Lighthouse. No special skill is required, and the equipment is inexpensive and lasts a lifetime. Newcomers are welcome. Email email@example.com or call 904-537-1999.
Reggae Sundays: Live Reggae music will be from 3 to 7 p.m. each Sunday through Sept. 30 at the Conch House Marina, 57 Comares Ave., on the island. Go to www.conch-house.com/reggae.html to view the music schedule.
The St. Augustine Flea Market: Fresh produce and a U-pick hydroponics farm is offered every Saturday and Sunday at The St. Augustine Flea Market, 2495 State Road 207. Hours are 8 a.m. to 4 p.m. both days, with free parking and admission. The market offers more than 200 booths. Call 824-4210 or go to www.stjohnsfleamarket.com.
Auditions: Flagler Playhouse will host auditions at 6 p.m. today and Sept. 3 for "The Uninvited" by Tim Kelly, directed by Stephen Pigman. Flagler Playhouse is at 301 E. Moody Blvd., in Bunnell. Actors are asked to arrive at least 15 minutes prior to 6 p.m. for registration. Actors are asked to prepare a short 1-2 minute comedic/melodramatic monologue in a British or Irish accent. Roles for men and women ages 17 and up. No roles have been pre-cast. Call 386-586-0773 or go to www.flaglerplayhouse.com.
Monday, Sept. 3
Concert in the Plaza: Jazz Piersonified & Friends will perform from 1 to 5 p.m. in the Plaza de la Constitucion, between Cathedral Place and King Street, in downtown St. Augustine. The band will perform jazz and "The Great American Songbook" tunes. Members are Fran Coraggio on bass; Jack Pierson on keyboard; Cindy Pierson on vocals; and Robert Bands on drums. Other local musicians also may join the group for this Labor Day show. Concertgoers should bring blankets or chairs for seating; alcohol is prohibited. Admission is free. Go towww.plazaconcerts.com, call 825-1004, or email email@example.com.
Labor Day fish fry: The St. Augustine Shrine Club will hold the annual Labor Day Fish Fry from 11:30 a.m. to 2 p.m. at the Shrine Clubhouse, 250 Brainard Drive. Donation is $9. The public is invited.
Labor Day picnic: The Palm Coast VFW, 47 Old Kings Road, will host a Labor Day Picnic from noon to 2 p.m. Tickets are $10 in advance or $11 at the door. In addition, there will be music and dancing. Call 386-446-8696.
Pirate ship treasure hunt: Ride the Black Raven as she battles with the Queen Anne's Revenge. The two ships trade cannon fire as they fight over Blackbeard's Treasure Chest. The children of the Black Raven will learn to swordfight to help the Black Raven's crew and will get their share of the "booty." Trips are set for 12:15 and 2:15 p.m. Cost is $34.95 for adults, $24.95 for children. Go to www.PirateShipBlackRaven.com or call 826-0000.
Sailing tour: Built for small groups, St. Augustine Eco Tours offers a sailing experience on a 27-foot catamaran sailboat. Observe wildlife such as dolphins, manatees and shorebirds, take in the scenery, unwind and relax. Tours departs daily at 3:15 and 5:45 p.m. from the St. Augustine Municipal Marina, 111 Avenida Menendez. Cost is $45 per person or $250 for the whole boat up to six passengers. Call 377-7245 for reservations.
Alligator Farm blood drive: The Saint Johns Blood Alliance and The St. Augustine Alligator Farm Zoological Park are teaming up to hold a blood drive from 10 a.m. to 2 p.m. Free admission will be given to all donors.
Tuesday, Sept. 4
Archaeological lecture: "Twenty Five Years of Discovery in St. Augustine" will be the topic of a lecture at 7 p.m. in the Flagler Room of Flagler College. The St. Augustine Archaeological Association and the Florida Public Archaeology Network will host City Archaeologist Carl Halbirt and archaeologist Mischa Johns as they discuss important excavations that have highlighted the 25 years since St. Augustine adopted our pioneering Archaeology Ordinance. The presentation is free and open to the public. Go to saaa.shutterfly.com or call 471-1870.
Swing dance lessons: Free swing dance lessons with Janine and Adam begin at 8:30 p.m. every Tuesday in Mardi Gras Sports Bar, 123 San Marco Ave. Beginner and experienced dancers are invited. Go to mardibar.com for more details.
Children's chorus rehearsals: The St. Augustine Children's Chorus is accepting new members in August and September for the coming season. The fall season will include December performances with the St. Augustine Community Chorus, the St. Augustine Beach Pier Illumination Festival and the Flagler College Singers. The chorus sings a varied repertoire of folk, classical, seasonal and Broadway music. The chorus meets from 4 to 5:30 p.m. Tuesdays; all singers ages 8 to 18 are welcomed. Call Kerry Fradley, director, to set up an interview or audition at 806-7781 or email firstname.lastname@example.com.
Wednesday, Sept. 5
Luncheon fashion tribute show: As a tribute to the late Lynn Anderson, who passed away on Aug. 26, a fashion show will be held at 11:30 a.m. in the Casa Monica Hotel in the 95 Cordova Restaurant. The show will feature Fresh Produce, known for high quality easy-care cotton knits that are great for travel and the St. Augustine lifestyle. Special guest model will be Alison Johnson, Director of Development for The St. Augustine Youth Services. Johnson will be available for questions and information about the new home for boys located on U.S. 1 South. The luncheon includes a free mimosa or champagne, choice of appetizer, entree, dessert and beverage for $19.95 per person. Reservations are recommended. Call 810-6810 for reservations.
Music by the Sea: The Orion Navy Band will perform from 7 to 9 p.m. in the pavilion of the St. Augustine Beach Pier, 350 A1A Beach Blvd., St. Augustine Beach. The group will jazz music. Amici's Italian Restaurant will begin serving dinner at 6 p.m., with meals at $10 or less. Admission is free; bring chairs or blankets for seating. The concert series will continue each Wednesday through Sept. 26. Go to www.thecivicassociation.com.
Photography contest: Anastasia State Park will conduct a photography contest starting Aug. 15 and ending Nov. 15. With an overabundance of wildlife, wildflowers and landscapes, photographer are encouraged to capture the beauty of the park. Pictures must be taken between Aug. 15 and Nov. 15, submitted with a photography entry form. Winners will be selected by a panel of judges including Friends of Anastasia Board of Directors, park managers and other various park staff. Prizes will be awarded and winners will be announced on or before Dec. 15. Categories are wildlife; landscapes; dusk and dawn; and people/activities.For official rules and submission forms, go to www.anastasiaphotographycontest.weebly.com. Call the park at 461-2033.
Marineland kayak ecotours: Naturalists from Ripple Effect Ecotours will offer Marineland kayak tours from 9 to 11:30 a.m. today and Aug. 25. Cost is $55 for adults and $45 for 15 years or younger, which includes free general admission into Marineland Dolphin Adventure, guide service and kayaking equipment. Call 347-1565 or go to www.RippleEffectEcotours.com.
St. Augustine Food Tour: Explore the diverse offerings of Saint Augustine as an expert, licensed guide makes the city's history come alive. Guests will receive generous tastings on this foodie tour, offered at 1:30 p.m. Wednesday through Saturday. For details, go to www.StAugustineHistoricTours.com or call 392-7137.
Texas Hold'Em Poker Tour: Sara's Crepe Cafe will host a Texas Hold'Em Poker Tour each Wednesday. Registration begins at 6 p.m., with the beginner table opening at 6:30 p.m., and the tournament to start at 7 p.m. Call 810-5800 or email firstname.lastname@example.com.
Wednesday market: This farmers market offers art, handmade and organic items, fresh fruit, veggies, bread and prepared food from local vendors from 7:30 a.m. to 12:30 p.m. at the St. Augustine Beach Pier on A1A Beach Boulevard. Free parking is available in the Pier parking lot.
Thursday, Sept. 6
Train concert: Rock band Train will take the stage at 6 p.m. at the St. Augustine Amphitheatre, 1340C A1A South. Tickets are $39.50; $59.50 and $65. Go to www.staugamphitheatre.com.
Salsa classes: A four-week salsa class will begin at 7 p.m. in Dancing with Victoria, 4420 U.S. 1 South. For information, go to www.chachavictoria.com or call 540-0225.
Kaylee Rose music: Local musician Kaylee Rose performs from 6 to 10 p.m. at Spy Global Cuisine, 21 Hypolita St. Go to www.kayleerosemusic.com.
Nobby's live music: Useless Eaters will headline with Tight Genes at Shanghai Nobby's, at 10 Anastasia Blvd. The 2416 will open the show. The concert will begin at 9 p.m. and cover charge is $5.
Jewish St. Augustine founding celebration: The St. Augustine Jewish Historical Society (SAJHS) will hold a 447th anniversary of The Founding of St. Augustine with a "Jewish component." The SAJHS hopes to make the 447th anniversary of the founding of St. Augustine a little bit different from the previous celebrations by noting the possibility of the first Jews, Marranos, Crypto-Jews, Conversos, New Christians arriving and settling in what was to become the United States. A special program will be from 4 to 5 p.m. at the Fountain of Youth Archaeological Park, 11 Magnolia Ave. The 60-minute program that includes a tour of the latest archaeological sites presented by the St. Augustine Archaeological Association's Carl Lindenfeld and Moises Sztylerman. A larger celebration will be held Sept. 8. This event is open to the public. Call 797-6770 and or go to staugustinejewishhistoricalsociety.wordpress.com.
Summer Dinner Theatre: "Check, Please," is on stage at Raintree Restaurant, 102 San Marco Ave. Tickets are $39.95 and include a special dinner menu and the show. Dinner is served at 6:30 p.m. and the show starts at 7:30 p.m. Call 824-7211 or go towww.RaintreeRestaurant.com.
Violin and jam sessions: Group violin lessons and jam sessions will begin at 5 p.m. Thursdays and Fridays with award-winning musician/instructor Allen Hood. All ages are welcome. Call 829-9829 or 824-1649 for more information.
Nia movement classes: Dance the Nia technique from 10 to 11:30 a.m. each Thursday at the St. Johns County Cultural Arts Center, 370 A1A Beach Blvd., next to the St. Augustine Beach pier. Nia includes 52 movies, dynamic music, and forms from the healing arts, martial arts and dance. Space is limited for the six-week sessions. For reservations, call 392-3272 or go towww.nianow.com/martyhenneka.
Boston Connection show: Local band the Boston Connection will perform from 5 to 8 p.m. each Thursday in Panama Hatties, 361 A1A Beach Blvd., St. Augustine Beach. Admission is free. Call 471-2192.
Piano music: Bob Fraioli plays solo piano from 5:30 to 9:30 p.m. every Thursday at Tini Martini Bar, 24 Avenida Menendez, at the Casablanca Inn on the bayfront. Call 829-6510.
Scrabble games: The St. Johns County Council on Aging will hold scrabble games from 1 to 4 p.m. Thursdays in the Conservatory of the River House, 179 Marine St. This is a casual social group and there is no cost and no pre-registration needed. Call 209-3643 or email@example.com.
Ongoing events
Archaeology at the Visitor Information Center: A new exhibit at the St. Augustine Visitor Information Center on San Marco Avenue offers a look into the extraordinary life of the Nation's oldest city through a collection of 58 artifacts - many of which are on display for the first time. These include buttons, pottery, eating and cooking utensils, a 1650 bocce ball, musket balls, a bayonet and more. The free exhibit is open daily from 8:30 a.m. to 5:30 p.m. From 10 a.m. to 2 p.m. each Wednesday, City Archaeologist Carl Halbirt and his volunteers will answer questions. The center is at 10 Castillo Drive, next to the parking garage in downtown St. Augustine.
Marineland Dolphin Adventure: The Touch & Feed program at Marineland is an engaging poolside experience that gives guests an up-close interaction with one of the bottlenose dolphins at the facility. Cost is $29 per person, ages 3 and older. Call 471-1111 or go to www.marineland.net.
Dow Museum of Historic Houses: The Dow Museum combines interactive experiences, exhibitions and objects to tell the story of Florida's historical and cultural development. This museum is made up of nine historic homes, dating from 1790 to 1910, as well as the collections of museum benefactor Kenneth Worcester Dow. The property highlights both St. Augustine and Florida history. Hours are 10 a.m. to 5 p.m. Monday through Satur4day, and 11 a.m. to 5 p.m. Sunday. The Spear Gallery on the property houses art exhibits by local artist. Suzanne Strock will exhibit new art July 6 through Sept. 7. Group tours and scavenger hunts for children. Tickets are $8.95 for adults, $7.95 for seniors 65 and older, $6.95 for students, and free for children 5 and younger. St. Johns County residents get free admission on the first Monday of each month. Entrance is at 149 Cordova St. Call 823-9722 or go to www.moas.org/dowmuseum.html.
Free admission: St. Johns County residents with ID are admitted free of charge to the Lightner Museum, 75 King St., 824-2874; the Fountain of Youth, 11 Magnolia Ave., 829-3168; Ximenez-Fatio House, 20 Aviles St., 829-3575; the Oldest Wooden Schoolhouse, 14 Saint George St., 824-0192; the Spanish Military Hospital Museum, 3 Aviles St., 827-0807; the San Sebastian Winery, 157 King St., 826-1594; the Authentic Old Drug Store, 31 Orange St., 824-2269; Fort Matanzas National Monument, 8635 A1A South, 471-0116; and the Peña-Peck House, 143 Saint George St., 829-5064.
Villa Zorayda Museum: Take a step back in time and explore this former grand Gilded Age home built in 1883 by Bostonian Franklin W. Smith. The museum is a one-tenth scale reproduction of a portion of the Alhambra Palace in Granada, Spain. Franklin Smith was the innovator of the poured concrete and crushed coquina construction that is seen throughout St. Augustine today. Learn the 129-year history of the Villa Zorayda during a state-of-the-art audio guided tour which run continuously throughout the day. The audio tour is available in English, Spanish and French. Admission for audio tours are $10 for adults ($1 discount for seniors age 60 and older, members of AAA and military and their families, $2 discount for all students ages 13 and older), and $4 for children ages 8 to 12, and children 7 and younger are admitted free. A 50-percent discount is extended to all St. Johns County residents with ID. Free all day parking comes with paid admission. Hours are 10 a.m. to 5 p.m. Monday through Saturday; and 11 a.m. to 4 p.m. Sunday. The museum is at 83 King St., across from Flagler College. Go to www.villazorayda.com or call 829-9887.
Pirate museum: Launched in December 2010, St. Augustine Pirate & Treasure Museum, 12 S. Castillo Drive, offers visitors a glimpse of the world's largest collection of authentic pirate artifacts dating back to the 16th century. Admission is $12.99 for adults; $6.99 for children 5 to 12; and free for 4 years and younger. Call 877-467-5863 or go to www.thepiratemuseum.com.
Black History Tours: Howard E. Lewis offers black history tours of the St. Augustine area including Lincolnville. Call 501-6878 or email email@example.com.
Saint Augustine walking tours: Tour Saint Augustine Inc. offers walking tours based on the themesof Henry Flagler, Civil Rights, Black History and Spanish Colonial History. Cost $12 for adults, $8 for children (ages 6-12), and free for ages 5 and younger. St. Johns County resident tickets are discounted by 50-percent. Times and departures vary. Call 1-800-797-3778 or or e-mail firstname.lastname@example.com.
Lighthouse for residents: St. Johns County residents who purchase full-price admission to the St. Augustine Lighthouse good for free admission for an entire year. Cost is $9.50 for adults; $7.50 for seniors and children 12 and under; and free for children under 44-inches in height.
Call 829-0745 or go to www.staugustinelighthouse.com.
Archaeo tours: The Lighthouse Archaeological Maritime Program (LAMP) will offer Archaeo Tours, a 90-minute tour to gain access into parts of the Historic Light Station not available with general admission, including maritime archaeology laboratory facilities. Tours are guided by one of the Lighthouse's archaeologist who make discoveries every summer on the Lost Ships of St. Augustine, wrecked off the coast of our nation's oldest port. Following the presentation, the tour will conclude with free time to explore museum exhibits in the historic Keepers' House, as well as an opportunity to climb the Lighthouse and enjoy endless St. Augustine views from 160 feet above ground. For those over the age of 21, an invitation also will be extended after the tour to join LAMP archaeologists for a complimentary adult beverage and refreshments. Go towww.staugustinelighthouse.org or call 829-0745 for reservations.
Flagler College tours: The Hotel Ponce de Leon is a a national historical landmark famous for its Tiffany Windows, ornate murals and Spanish-Renaissance architecture. Tours are held through the summer at the top of each hour, from 10 a.m. to 3 p.m., departing from the main lobby (Rotunda), at 74 King St. Tickets may be purchased at this location 15 minutes prior to each tour, or at Flagler's Legacy, 59 Saint George St. Cost is $7 for adults, $5 for St. Augustine residents with a valid ID, and $1 for children under the age of 12. Reservations are not required. For group rates, call 823-3378. For reservations, call 819-6400.
Daily Lighthouse tours: The St. Augustine Lighthouse and Museum is offering a Behind the Scenes tour that gives guests a deeper understanding of how the Lighthouse and its archaeological team are attempting to preserve St. Augustine's history. This guided tour provides visitors the chance to view authentic, shipwreck artifacts and parts of the Historic Light Station not available with general admission, including stops in the conservation lab and office of the Lighthouse Archaeological Maritime Program. Visitors also will experience life as a keeper in the late 1800s and of course, enjoy the opportunity to climb the 219 steps to the top of the tower to take in the beautiful view from 140 feet above ground. For dates and times, call 829-0745, ext 201. Reservations are welcome.
Pub crawl: Take a pub crawl from 5 to 7:30 p.m. daily (and also at 2 p.m. Friday, Saturday and Sunday) through the streets and into the local drinking establishments of downtown St. Augustine. The departure point is Ann O'Malleys Pub, 23 Orange St., with parking nearby in the parking garage on Castillo Drive. Meet with a licensed city tour guide 15 minutes prior to the departure at 5 p.m. Cost is $34 per person and includes a draft beer or soda at each of the five pub stops. Make online reservations at www.staugustinepubcrawl.com, e-mail email@example.com or call 540-3476.
Saint Augustine walking tours: Tour Saint Augustine Inc. is offering walking tours based on the themes of Henry Flagler, Civil Rights, Black History and Spanish Colonial History. Cost $12 for adults, $8 for children (ages 6-12), and free for ages 5 and younger. St. Johns County resident tickets are discounted by 50-percent. Times and departures vary. Call 1-800-797-3778 or or e-mail firstname.lastname@example.com.
Savory Faire culinary tour: A walking tour beginning at 2 p.m. Mondays, Wednesdays and Fridays will explore the historical and cultural influences on the tastes of St. Augustine throughout the centuries. From Tapas to desserts, journey from the first Thanksgiving to present day culinary offerings of the city. Cost is $45 per person and includes one bottled water at the start of the tour, all tastings at five food establishments, and a special heritage recipe gift. Call 540-3476.
Marineland Behind the Seas tour: Marineland Dolphin Adventure is celebrating the opening of the Behind the Seas tour. Guests can experience the behind the scenes tour for $17 for adults, $8 for children and $14.50 for seniors. Tour prices include general admission. Marineland is at 9600 Oceanshore Blvd. (A1A South), in the town of Marineland. Call 471-1111 or go to www.marineland.net.
Society of Mixed Media Artists exhibition: Featuring selected artist members from SoMMA curated by David Engdahl and Jan Miller, this exhibit is free to the public. Regular exhibition hours are 9 a.m. to 5 p.m. daily through Sept. 1 in the Cultural Center of Ponte Vedra Beach, 50 Executive Way. Call 280-0614 or go to www.ccpvb.org.


text:
|Fall Term 2018 Internship in Russian - RUSS 595
Prerequisites/Notes: Counter Registration Required.
Catalog Description : An opportunity for students to apply their Russian language skills in business, government, and the non-profit sector on the regional, national, and international levels. Arranged in collaboration with and supervised by a member of the department. Includes discussion, report, and/or portfolio. Advance consultation and application required. Credit may be given for internships completed during a period of study abroad.
Attributes: BM Humanities (01cr), Advanced Course

subset: commoncrawl


text:
OLD HICKORY Custom Pro AP5 Adult Wood Baseball Bat
Product Code: OHAP5
Availability: Custom Made To Order
Availability: Custom Made To Order
Price: $95.00
The AP1 is a custom model similar to a C243 style of bat. Built for a power hitter it has a large barrel and a tapered handle. Considering its barrel size this model has really good balance. We like this model for more seasoned wood bat users.
|Custom made to order just for you. Please allow 2-4 weeks for delivery in most cases
|Similar to a C243
|Tapered Knob
|1 1/8" Bottom Hand
|15/16" Top Hand
|2.5" Barrel
|A flat finish is available with most handle options for those who don't like a clear lacquer on the grip
|Choose from Pro Ash, Pro Ink Dot Certified Birch or Pro Ink Dot Certified Maple
Write a reviewYour Name:
Your Review: Note: HTML is not translated!
Rating: Bad Good
Enter the code in the box below:


text:
This week, the Open Source Karma has been cast-aside. We're going proprietary in a big way. We're going to the very heart of Oracle's power, deep inside the RDBMS – yes – it's PL/SQL.
This post is dedicated to ( and essentially co-written by) Simon. Yes, my long-time best mate, long-time Luton Town fan, long-time Teradata expert and long time everything really ( we'll he's not as young as he was).
After all these years, Simon has become a bit curious about this PL/SQL thing I'm always going on about and would like to know more.
It is this desire – and large amounts of beer – that has persuaded him to play the Igor to my mad scientist and have a wander through this very quick guide to the language at the heart of most Oracle applications. In fact we came up with several possible descriptions of Simon's role in this post, but he had a "hunch" that this was the right one.
So for him, and any other programmers who want to get up and running with PL/SQL, but don't need to be told what a variable is, what follows is – not so much a PL/SQL 101 – as a PL/SQL 23-and-a-bit.
I want to get you up and running in PL/SQL as quickly as possible, so I'm not going to go into long explanations about SQLDeveloper, SQL or even too much about the Oracle RDBMS itself. It's also not a best practice guide. It's aimed at simply giving you enough information to get playing with PL/SQL. I've added some further links at the end that may be of interest.
I'm going to start by making a number of assumptions about you.
First, you have some experience of a high-level programming language ( e.g. C, Java, VB) so, like Simon, you know what a variable is and how to use it.
Secondly, I'm going to assume that you have at least a working knowledge of SQL.
Third – I'll assume that you have an Oracle database available to play on. Indeed, I've made sure that all of the examples here will work on Oracle Express Edition ( Oracle XE) – Oracle's free version of their RDBMS.
You can get Oracle Express Edition from here.
If you are one of those hardy souls who wants to run it on Ubuntu, alternative instructions on how to download and install can be found here.
SQLDeveloper is also from Oracle and also free. You can get it from here (I'd suggest you go for either 2.1 or 3.0 Early Adopter at the time of writing as 2.1.1 has one or two "quirks").
Finally, I'm assuming here that your HR user has been unlocked. If not, you need to connect to the database as system and unlock the account. If you connect in SQL*Plus, you need to run :
ALTER USER hr UNLOCK /
Incidentally, it's good practice to change the password of these default users ( such as hr) when you unlock them for security reasons. You can do this as follows ( still as system) :
ALTER USER hr IDENTIFIED BY new_pwd /
Where new_pwd is the password you want to set for the hr user.
For the remainder of this post, I'm going to assume that the hr user has it's default password. If you do change it then you need to substitute the password "hr" with the one you've set for it when connecting using the following examples.
This PL/SQL Thing – What is it ?
Procedural Language SQL is, in essence, the Ada programming language with SQL extensions built into the Oracle RDBMS. It enables you to enforce complex business rules that you couldn't otherwise implement through SQL or a relational design.
It also allows you to write application logic in the database.
How do I get to it ?
Generally speaking, anywhere you can get to enter an SQL statement. You need to be connected to a running database. Essentially this means SQL*Plus ( from the command line) or SQLDeveloper ( or similar IDE).
A small bit of admin before we get going – you may want to create a separate directory to save your PL/SQL scripts to (e.g. c:\pls_progs on windows or $HOME/pls_progs on Linux).
If you're running an Oracle client ( or XE for that matter), part of the default install will have been to add the software to your path so, whether your on Linux or Windows, you should be able to do the following from Terminal / Command Window :
sqlplus hr/hr@XE
My preferred way of working is to use a text editor to write code and save to files and then run the code in SQL*Plus. This is the method I'm using throughout this post. There are other options open to you, however.
With SQLDeveloper, make sure you're connected to the database and you're ready to go.
Run SQL Command Line Menu Option
If you've installed Oracle XE, under the Oracle Database 10g Express Edition Menu, you'll have an option called Run SQL Command Line.
If you open this, you can connect as follows ( in this example, the user your connecting as is hr with a password of hr and the database is called XE) :
conn hr/hr@XE
In both Windows and Linux, we do need make some alterations to persuade this menu option to point to our preferred directory ( i.e. c:\pls_progs – where we're going to save our PL/SQL files to).
In Windows, you simply need to go to the shortcut on the menu and right-click; select properties from the pop-up menu and then enter c:\pls_progs as the startup directory.
In Linux, things are a little more involved – we need to set the SQLPATH environment variable so that the script starting the command line picks it up. To do this, open a Terminal Window and :
cd /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/config/scripts sudo gedit sqlplus.sh
Then add the definition of the SQLPATH variable. The whole script should look something like this :
#!/bin/bash # # svaggu 09/28/05 - Creation # ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server export ORACLE_HOME ORACLE_SID=XE export ORACLE_SID NLS_LANG=`$ORACLE_HOME/bin/nls_lang.sh` export NLS_LANG PATH=$ORACLE_HOME/bin:$PATH export PATH # Added line to set working directory of the SQL command line SQLPATH=/home/mikes/pls_progs export SQLPATH sqlplus /nolog
After all that, it's finally time to meet…
The Block with No Name
Actually it's known as an Anonymous Block, a PL/SQL program that is not stored in the database ( Stored Program Units), but which is normally saved to a file.
Now, for the most part, PL/SQL programs perform I/O against database tables. However, tradition dictates that the first program in a guide such as this must write out some twee message to the screen. So….
set serveroutput on BEGIN DBMS_OUTPUT.PUT_LINE('Do ya feel lucky, punk ?'); END; /
Save the file as lucky.sql in the directory you've just created – then go to the SQL prompt and run ( or with the file open in SQLDeveloper, hit F5) :
SQL*Plus: Release 10.2.0.1.0 - Production on Sun Oct 17 21:49:11 2010 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production SQL> @lucky.sql Do ya feel lucky, punk ? PL/SQL procedure successfully completed. SQL>
Yes, tiresome and tortuous link – Block with No Name, Man with No Name , Clint Eastwood, Dirty Harry.
More immediately relevant, executable statements are terminated with a ";"
We can also see that PL/SQL is a Block Structured Language. The full skeleton structure of a block is :
DECLARE -- variable declarations go here ( also terminated by a ; ) BEGIN --executable statements go in this bit. BEGIN is mandatory EXCEPTION --any errors are handled in this bit ( optional) END; --Note the ; after the mandatory END keyword /
The slash means run the block
Incidentally — is a single line comment. You can also use /* */ for multi-line comments.
One other point to note – PL/SQL is not case sensitive. Begin = begin = BEGIN. You can use uppercase, lowercase, you can even use camel case and PL/SQL won't get the hump. This also applies to any stored program units you call (we'll get onto them later). As you'd expect, string comparisons are case sensitive – 'SIMON' does not equal 'Simon'.
Let's take this example and make it a bit more realistic. First, we'll create a table and then use PL/SQL to insert a row.
NOTE – at this point you may want to use a separate user so that the objects created in these examples don't get mixed up with the HR schema, which is used in lots of Oracle tutorials.
So, if you're playing around on XE, you can create a user by connecting to the database as system and running the following :
GRANT connect, resource TO igor identified by igor / GRANT SELECT on hr.departments to igor / GRANT SELECT on hr.employees TO igor /
Now connect as the new user in the same way as for the HR user. The connect string in this example is igor/igor@xe
CREATE TABLE silly_messages ( message VARCHAR2(75)) /
Now the script to insert the row…
DECLARE l_msg VARCHAR2(75); BEGIN l_msg := 'Well, do ya ?'; INSERT INTO silly_messages( message) VALUES( l_msg); END; /
Save the file as ins_msg.sql and off we go….
SQL> @ins_msg.sql PL/SQL procedure successfully completed. SQL> select * from silly_messages; MESSAGE -------------------------------------------------------------------------------- Well, do ya ? SQL> commit; Commit complete.
Note the COMMIT – you need to issue this command to save the change to the database.
This time we've declared a variable and assigned it a value, so it's probably a good time to whiz through :
Datatypes and Operands
Datatypes first – you can use any of the standard oracle database datatypes ( DATE, NUMBER VARCHAR2 etc).
VARCHAR2 is a bit of an odd one. First off, in other databases, it's VARCHAR. Secondly, in PL/SQL you can define it as up to 32767 characters, but the maximum length in a database table is only 4000.
Additionally, you'll probably come across the following types quite a lot in PL/SQL :
– PLS_INTEGER ( or it's predecessor BINARY_INTEGER) – an integer between -2,147,483,647 and 2,147,483,647
– table.column%TYPE – declares a variable to be of the same type as the table.column specified
– CURSOR – I'll come onto this in a bit.
All the usual suspects are here ( + – * /) and you can generally use any SQL functions in-line in PL/SQL.
Points to note are that the equality operator is = and the assignment operator is :=
There are no increment/decrement operators ( ++ or – -) . In order to increment a numeric variable by 1, you'd write :
l_num := l_num + 1;
When you insert or update data in Oracle, the change isn't saved until the transaction is either committed or rolled back. A transaction can span multiple DML statements.
To save changes to the database you need to issue a COMMIT ( as above). To undo your changes, it's ROLLBACK;.
NOTE any DDL statement will also end and commit a transaction. That's generally any statement beginning with CREATE, ALTER or DROP.
If you don't COMMIT your changes, then by default, they'll be rolled back when you end your session – i.e. they won't be saved.
If Feel Lucky Then…
Moving swiftly on, time for a quick word about conditional statements and loops.
As so much of modern mathematics ( and therefore computing), emanated from the Arab world, it is in some small way fitting that I learned to avoid a common pitfall with the PL/SQL IF THEN ELSE syntax from a picture not unlike this one :
Whilst we're here, we may as well meet the FOR loop at the same time as it's probably the most commonly used loop construct in PL/SQL :
set serveroutput on DECLARE l_msg silly_messages.message%TYPE; BEGIN FOR bullet in 1..6 LOOP IF bullet < 5 THEN l_msg := 'BANG!'; ELSIF bullet = 5 THEN l_msg := 'Whatever you say, officer.'; ELSIF bullet = 6 THEN l_msg := q'[That's a big gun. Are you compensating for something ?]'; END IF; INSERT INTO silly_messages( message) VALUES( l_msg); END LOOP; END; /
Save this one as bullets.sql and …
SQL> @bullets.sql PL/SQL procedure successfully completed. SQL> select * from silly_messages; MESSAGE -------------------------------------------------------------------------------- Well, do ya ? BANG! BANG! BANG! BANG! Whatever you say, officer. That's a big gun. Are you compensating for something ? 7 rows selected. SQL> commit;
We can see that the loop variable bullet is declared implicitly – PL/SQL saves us the bother.
The FOR loop is the most commonly used largely due to it's relationship to the CURSOR ( see, I told you I'd mention them).
Cursors and For Loops
There are two types of cursor – implicit ( that return only a single row) and explicit.
An explicit cursor can be thought of as a statement that will generate a result set that we can then manipulate in PL/SQL.
Once again, because it's the law, we'll have a look at a sensible example, this time using the EMPLOYEES and DEPARTMENTS tables in the HR schema.
set serveroutput on DECLARE l_dname hr.departments.department_name%TYPE; l_deptno hr_departments.department_id%TYPE; CURSOR c_depts IS SELECT department_name, department_id FROM hr.departments ORDER BY department_id; BEGIN OPEN c_depts; FETCH c_depts INTO l_dname, l_deptno; CLOSE c_depts; DBMS_OUTPUT.PUT_LINE( 'Department Name - '||l_dname||' id - '||l_deptno); END; /
Save as exp_cursor.sql and run the script…
SQL> @exp_cursor.sql Department Name - Administration id - 10 PL/SQL procedure successfully completed. SQL>
Don't forget the set serveroutput on or PL/SQL will get all tight-lipped and not print out the DBMS_OUTPUT lines. Incidentally, Elsif has some strong opinions on the subject of serveroutput. Roughly translated – it's all one word.
Explicit cursors ( like c_depts in this example) are declared explicitly in the DECLARE section.
You then need to OPEN them, FETCH them INTO the appropriate variables and CLOSE them when you're done.
You'll notice that we only get one row back here as we only do a single fetch of the cursor.
Explicit cursors are commonly used with FOR loops ( incidentally, you can also pass parameters to an explicit cursor) :
set serveroutput on DECLARE CURSOR c_emp( cp_dept_id hr.employees.department_id%TYPE) IS SELECT first_name, last_name, hire_date FROM hr.employees WHERE department_id = cp_dept_id; l_emp_count PLS_INTEGER; BEGIN -- -- Implicit cursor – returns one row, no more, no less -- SELECT COUNT(*) INTO l_emp_count FROM hr.employees WHERE department_id = 30; IF l_emp_count > 0 THEN -- -- Cursor For Loop – r_emp is a record of the type of the select statement in the cursor -- FOR r_emp IN c_emp(30) LOOP DBMS_OUTPUT.PUT_LINE( r_emp.first_name||' '|| r_emp.last_name||' '|| r_emp.hire_date); END LOOP; END IF; END; /
You'll notice that, once again, the loop variable is implicitly declared. This time however, it's a record conatining each column returned by the cursor. A cursor can be any valid SELECT statement.
I've also used an implicit cursor here. Because we're doing a SELECT COUNT(*), it will always return exactly one row. If an implicit cursor returns either no rows or more than one, you will get an error.
Anyway, save the code as cursor_for.sql, run it and you should get :
SQL> @cursor_for.sql Den Raphaely 07-DEC-94 Alexander Khoo 18-MAY-95 Shelli Baida 24-DEC-97 Sigal Tobias 24-JUL-97 Guy Himuro 15-NOV-98 Karen Colmenares 10-AUG-99 PL/SQL procedure successfully completed. SQL>
Other Looping Constructs
Whilst we're on the subject of loops, we may as well cover the WHILE loop and Simple LOOP as well.
DECLARE l_msg silly_messages.message%TYPE; l_bullets PLS_INTEGER :=1; BEGIN WHILE l_bullets <= 6 LOOP l_msg := 'BANG'; INSERT INTO silly_messages( message) VALUES( l_msg||'-'||l_bullets); l_bullets := l_bullets +1; END LOOP; l_msg := 'Click'; INSERT INTO silly_messages( message) VALUES(l_msg); END; /
Yep, that's a while loop. Now for a simple loop :
DECLARE l_count PLS_INTEGER; l_msg silly_messages.message%TYPE; BEGIN l_count := 1; LOOP IF MOD( l_count, 2) = 0 THEN l_msg := l_count||' is even'; ELSE l_msg := l_count||' is odd'; END IF; INSERT INTO silly_messages( message) VALUES( l_msg); l_count := l_count + 1; EXIT WHEN l_count > 10; END LOOP; END; /
In the previous examples you'll also notice the variable assignment on declaration ( l_bullets PLS_INTEGER := 1;) and concatenation of variables of different types that can then be inserted into a VARCHAR2 column ( l_msg||'-'||bullets);.
The Curious Case of CASE
At this point, I should mention the CASE statement ( thanks Si). I'm skimming over it for two reasons. First, it's a comparatively new construct in PL/SQL and so you probably won't find too many instances of it in applications that have been around any length of time.
The second is that Bryn Llewellyn, Oracle's PL/SQL Product Manager, has done a pretty good job of explaining matters here.
Exceptions – When it all goes horribly wrong
The EXCEPTIONS section is where you handle any errors. When an error is encountered in a block, control passes to the EXCEPTION handler, if it exists. Once the error is processed, the block terminates – control does not pass back to the main body of the block.
Oracle has tens of thousands of errors it can throw up, so you'll probably find the most common EXCEPTION handler is the catch-all WHEN-OTHERS exception.
To demonstrate – first create a table :
CREATE TABLE tiny( little VARCHAR2(10)) /
Now try to insert a record that's longer than the column will hold. Save the file as exception.sql.
set serveroutput on BEGIN INSERT INTO tiny(little) VALUES('Room for a small one ?'); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Oops : '||SQLERRM); END; /
Running this, we get :
SQL> @exception.sql Oops : ORA-12899: value too large for column "HR"."TINY"."LITTLE" (actual: 22, maximum: 10) PL/SQL procedure successfully completed. SQL>
All we've done here is to output the error via the SQLERRM environment variable, which holds the text of the last error.
You'll notice that, as we've handled the exception, Oracle reports that the PL/SQL block was completed successfully.
Often you will be calling PL/SQL programs from other programs ( PL/SQL and otherwise). In order to make sure that the calling program is aware that there's been a problem further down the chain, you'll need to re-raise the error with the RAISE command. Save the following as raise.sql and run it :
BEGIN INSERT INTO tiny(little) VALUES('Room for a small one ?'); EXCEPTION WHEN OTHERS THEN RAISE; END; /
SQL> @raise.sql BEGIN * ERROR at line 1: ORA-12899: value too large for column "HR"."TINY"."LITTLE" (actual: 22, maximum: 10) ORA-06512: at line 4 SQL>
As you can see, the error is passed back to the caller ( in this case the SQL*Plus command line). As it's not handled by the caller, it falls over in a heap and PL/SQL doesn't think it's completed successfully.
As Simon pointed out, you get two errors reported in the stack – ORA-12899 at line 1 and ORA-06512 at line 4.
In common with many languages, it's usually the first error reported that you need to worry about in PL/SQL , so you usually want to fix that first and re-run the code before looking for any other problems reported by the compiler.
Have a look here for another example of this phenomenon.
A Cautionary Note on Transaction Control
This chain of calls to PL/SQL program units means that you need to be pretty careful where you put your commit and rollback statements. Ideally, transaction control should be done by the topmost program in the chain (In most cases, this will involve the end-user hitting a Save button). Otherwise, you may well get inconsistent data from commits where some of the processing has worked and some has errored.
For the purposes of this article, we'll assume that the caller is whatever SQL client you're using ( SQL*Plus or SQLDeveloper etc) and we'll manually issue the COMMIT and ROLLBACK statements.
All the stuff so far is all very well, but there's a lot more to PL/SQL than insulting heavily armed Law Enforcement Officers.
Stored Program Units
As I've said, PL/SQL is built right into the Oracle RDBMS. Most of the PL/SQL code that is written is stored in the database's Data Dictionary. These stored program units are Functions, Procedures, Packages and Triggers.
The Wonderful Thing About Triggers…
Apologies for the Winnie the Pooh reference – Simon insisted ( honest).
Triggers are a bit different from other Stored Program Units in that they are (almost always) associated with Tables and the code in them executes when a specified DML action takes place on the relevant table ( i.e. an Insert, Update or Delete).
A trigger can fire either before or after a DML action, either for every row affected by the DML statement, or after the entire statement.
NOTE – in Oracle 11g you can combine row and statement level commands in the same trigger, but we'll leave that aside for now.
Time to create another table to play with. Dirty Harry's gone for a lie-down ( like Simon, he's knocking on a bit), so let's choose something a bit more contemporary…
CREATE TABLE pop_princesses( track_id NUMBER PRIMARY KEY, artist_name VARCHAR2(50) NOT NULL, track_name VARCHAR2(50) NOT NULL, created_by VARCHAR2(30) NOT NULL, creation_date DATE NOT NULL, modified_by VARCHAR2(30), modified_date DATE) /
Unlike other RDBMSs ( such as MySQL), Oracle does not have the facility to specify an automatically incrementing synthetic key value in a CREATE TABLE statement, so also need a sequence to populate pop_princesses.track_id :
CREATE SEQUENCE pp_track_id_seq START WITH 1 /
We want to automatically record who created each record in this table and when. We also want to keep track of the user who last modified each record and when.
Bounce forward, the trigger :
CREATE OR REPLACE TRIGGER pp_biu BEFORE INSERT OR UPDATE ON pop_princesses FOR EACH ROW BEGIN IF INSERTING THEN :new.created_by := USER; :new.creation_date := SYSDATE; ELSIF UPDATING THEN :new.modified_by := USER; :new.modified_date := SYSDATE; END IF; END; /
In a row level trigger, you can reference existing values in the record being updated by prefixing the table column name with : old and new values by prefixing with :new.
This allows you to make changes to the values being altered. Now let's put some data into the table and have a look at the effect of the insert portion of the trigger :
INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'BEYONCE','CRAZY IN LOVE') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'GIRLS ALOUD','SOUND OF THE UNDERGROUND') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'AGNES','RELEASE ME') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'EVANESCENCE','BRING ME TO LIFE') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'SOPHIE ELLIS-BEXTOR','TAKE ME HOME') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'LILLY ALLEN','THE FEAR') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'AMY WINEHOUSE','REHAB') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'MOTORHEAD AND GIRLSCHOOL', q'[PLEASE DON'T TOUCH]') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'LADY GAGA', 'JUST DANCE') / INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, 'BRITNEY SPEARS', q'[I LOVE ROCK 'N' ROLL]') /
SQL> select track_id, artist_name, created_by, creation_date 2 from pop_princesses; TRACK_ID ARTIST_NAME CREATED_BY CREATION_DATE ---------- ------------------------------ ---------- ------------------ 1 BEYONCE IGOR 27-OCT-10 2 GIRLS ALOUD IGOR 27-OCT-10 3 AGNES IGOR 27-OCT-10 4 EVANESCENCE IGOR 27-OCT-10 5 SOPHIE ELLIS-BEXTOR IGOR 27-OCT-10 6 LILLY ALLEN IGOR 27-OCT-10 7 AMY WINEHOUSE IGOR 27-OCT-10 8 MOTORHEAD AND GIRLSCHOOL IGOR 27-OCT-10 9 LADY GAGA IGOR 27-OCT-10 10 BRITNEY SPEARS IGOR 27-OCT-10 10 rows selected. SQL>
As we can see, the created_by and creation_date columns have been populated by the trigger.
Some record exec somewhere has decided that Britney needs to be more grammatically correct in order to get her career back on track. Look, I needed a pretext for demonstrating the update part of the trigger and he owed me a favour – so…
SQL> UPDATE pop_princesses 2 SET track_name = 'I LOVE ROCK AND ROLL' 3 WHERE track_id = 10 4 / 1 row updated. SQL> SELECT track_name, modified_by, modified_date 2 FROM pop_princesses 3 WHERE track_id = 10 4 / TRACK_NAME MODIFIED_BY MODIFIED_DATE -------------------- ------------ ------------------ I LOVE ROCK AND ROLL IGOR 27-OCT-10 SQL> commit;
You can use any valid PL/SQL statements in a trigger, including calls to other stored program units.
This also means that they can be used to enforce business rules that couldn't otherwise be implemented using referential integrity constraints. All of which brings me nicely onto…
Like other languages, functions in PL/SQL typically follow the pattern of taking in a parameter or parameters, doing something with them, and returning a result.
CREATE OR REPLACE FUNCTION get_artist( pa_track_id IN pop_princesses.track_id%TYPE) RETURN VARCHAR2 IS l_artist pop_princesses.artist_name%TYPE; BEGIN SELECT artist_name INTO l_artist FROM pop_princesses WHERE track_id = pa_track_id; RETURN l_artist; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 'No track with this ID'; WHEN OTHERS THEN RAISE; END; /
A couple of items of interest here – we're using the pre-defined Oracle exception NO_DATA_FOUND in the Exception block. This is what gets raised when an implicit cursor returns no rows. If an implicit cursor were to return more than one row, we'd get a TOO_MANY_ROWS exception.
The other point to note is that the RETURN statement ends processing, irrespective of what comes after.
Save the above as get_artist_fn.sql and run it.
SQL> @get_artist_fn.sql Function created.
A function can return any PL/SQL datatype. However, if it does return a datatype that SQL recognizes, you can call it directly from within a SQL statement.
SQL> select get_artist(1) from dual; GET_ARTIST(1) --------------------- BEYONCE
Although you don't specify a length constraint either for a parameter or a return value, you can use the %TYPE declaration for both and the function will still work in exactly the same way. For example, if we specified the return value of this function as :
RETURN pop_princesses.artist_name%TYPE
We can still call this from SQL directly as it resolves to a VARCHAR2.
By contrast, because the following function does not return a SQL datatype, it can only be called from a PL/SQL block :
CREATE OR REPLACE FUNCTION is_artist_on_album( pa_artist_name pop_princesses.artist_name%TYPE) RETURN BOOLEAN IS l_dummy PLS_INTEGER; CURSOR c_on_album( cp_artist_name pop_princesses.artist_name%TYPE) IS SELECT 1 FROM pop_princesses WHERE artist_name = cp_artist_name; BEGIN OPEN c_on_album( pa_artist_name); FETCH c_on_album INTO l_dummy; IF c_on_album%FOUND THEN CLOSE c_on_album; RETURN TRUE; END IF; CLOSE c_on_album; RETURN FALSE; END; /
The RETURN type is defined as BOOLEAN so we can only call it from PL/SQL.
Incidentally, the %FOUND cursor characteristic we're using here returns TRUE if a row has been fetched from an explicit cursor. The counterpart to it is %NOTFOUND, which returns TRUE if a record has not been found.
In functions, RETURN terminates processing. It's worth remembering this, if only so you remember to close any explicit cursors before issuing the RETURN statement.
Anyway, save the function and run it. Then we can call it using an anonymous block :
SQL> @is_artist_on_album_fn.sql Function created.
Now create the caller ( save as call_is_artist_on_album.sql)
set serveroutput on BEGIN IF is_artist_on_album( pa_artist_name => 'LADY GAGA') THEN DBMS_OUTPUT.PUT_LINE('That Girl gets everywhere'); ELSE DBMS_OUTPUT.PUT_LINE('Vegetarians only then'); END IF; END; /
Note the line is_artist_on_album( pa_artist_name => 'LADY GAGA')
This illustrates one major difference between calling a function from PL/SQL and from SQL – in PL/SQL, you can pass values by reference rather than position using this syntax.
And run…
SQL> @call_is_artist_on_album.sql That Girl gets everywhere PL/SQL procedure successfully completed. SQL>
It was at this point that Simon proved that a Winnie The Pooh fixation is no bar to programming aptitude and came up with a far more elegant version of this function :
CREATE OR REPLACE FUNCTION is_artist_on_album( pa_artist_name pop_princesses.artist_name%TYPE) RETURN BOOLEAN IS l_dummy PLS_INTEGER; l_found BOOLEAN := FALSE; CURSOR c_on_album( cp_artist_name pop_princesses.artist_name%TYPE) IS SELECT 1 FROM pop_princesses WHERE UPPER(artist_name) LIKE cp_artist_name; BEGIN OPEN c_on_album('%'||UPPER(pa_artist_name)||'%'); FETCH c_on_album INTO l_dummy; l_found := c_on_album%FOUND; CLOSE c_on_album; RETURN l_found; END; /
To this point, I've been working on the basis that all strings inserted into the database are in uppercase. There are some fairly solid reasons for doing this but I'm not going into them now. Suffice to say that, with Simon's improved version of the function, we can edit the calling script ( call_is_artist_on_album.sql) as follows :
set serveroutput on BEGIN IF is_artist_on_album( pa_artist_name => 'Motorhead') THEN DBMS_OUTPUT.PUT_LINE('How did they manage that ?'); ELSE DBMS_OUTPUT.PUT_LINE('Nope - off making beer adverts'); END IF; END; /
And now we can run it and see….
SQL> @call_is_artist_on_album.sql How did they manage that ? PL/SQL procedure successfully completed. SQL>
It seems that Simon has tired of his role as Igor and is now lurching down the path toward the village.
Procedures differ from functions in that they don't return a value ( although they can pass back values to the caller by means of an OUT parameter).
Where PL/SQL comes into it's own is applying rules that can't otherwise be enforced by standard RI constraints.
For example, you know how artists can be a little…temperamental…
CREATE OR REPLACE PROCEDURE add_princess( pa_artist_name IN VARCHAR2, pa_track_name IN VARCHAR2) IS l_last_artist pop_princesses.artist_name%TYPE; CURSOR c_last_artist IS SELECT artist_name FROM pop_princesses WHERE track_id = ( SELECT MAX( track_id) FROM pop_princesses); -- -- user defined exception - that's new -- e_catfight EXCEPTION; BEGIN -- -- Get the last artist on the album at present -- OPEN c_last_artist; FETCH c_last_artist INTO l_last_artist; CLOSE c_last_artist; -- -- Unless the table is empty, we should have one -- IF l_last_artist IS NOT NULL THEN -- -- Now check to see what the new artist name is -- IF l_last_artist = 'BRITNEY SPEARS' AND pa_artist_name = 'CHRISTINA AGUILERA' THEN RAISE e_catfight; END IF; END IF; INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, pa_artist_name, pa_track_name); EXCEPTION WHEN e_catfight THEN -- -- Raise our own error - works the same as an Oracle error -- RAISE_APPLICATION_ERROR( -20000, 'Cannot put '||l_last_artist||' and '||pa_artist_name ||' together. Fur will fly!'); WHEN OTHERS THEN RAISE; END; /
Apart from keeping Divas apart, this procedure also extends the concept of EXCEPTIONS by introducing a user-defined exception, in this case e_catfight.
We can then raise an application error with an appropriate error number ( between -20000 and -20999). Let's see it in action :
BEGIN add_princess( pa_artist_name => 'CHRISTINA AGUILERA', pa_track_name => 'BEAUTIFUL'); END; /
With the script saved as call_add_princess.sql :
SQL> @call_add_princess.sql BEGIN * ERROR at line 1: ORA-20000: Cannot put BRITNEY SPEARS and CHRISTINA AGUILERA together. Fur will fly! ORA-06512: at "IGOR.ADD_PRINCESS", line 41 ORA-06512: at line 2 SQL>
If we try that again, but with a different artist :
BEGIN add_princess( pa_artist_name => 'BLONDIE', pa_track_name => 'CALL ME'); END; /
Save the changes to call_add_princesses.sql and :
SQL> @call_add_princess.sql PL/SQL procedure successfully completed. SQL> SELECT track_id, artist_name, track_name 2 FROM pop_princesses 3 WHERE track_id = ( 4 SELECT MAX( track_id) 5 FROM pop_princesses); TRACK_ID ARTIST_NAME TRACK_NAME ---------- ------------------------------ -------------------- 11 BLONDIE CALL ME SQL> COMMIT;
I had to work in a Debbie Harry reference somewhere as my girlfriend looks a bit like her – only much prettier. Honestly, if I could just remember her birthday, I wouldn't have to write stuff like this!
Packages are primarily used to group together related functions and procedures.
In many applications, the vast majority of functions and procedures are contained in packages.
The usual way of creating a package is to create a header ( aka specification) and then a body.
The header contains definitions of the functions and procedures in the package that are publicly available.
It also contains package variables which are visible to all package members, and outside of the package itself.
The body contains the actual code for each package member, together with any private package members – callable only from other members of this package. All this talk of members puts me in mind of a bunch of MP s…possibly in a pole dancing club, so I'll refer to these Package program units by their other generic name of packaged procedures henceforth ( yes, even the functions).
OK – the package header first :
CREATE OR REPLACE PACKAGE manage_princesses AS FUNCTION catfight( pa_new_artist IN pop_princesses.artist_name%TYPE, pa_last_artist IN pop_princesses.artist_name%TYPE) RETURN BOOLEAN; PROCEDURE add_princesses( pa_artist_name IN VARCHAR2, pa_track_name IN VARCHAR2); FUNCTION get_artist( pa_track_id IN pop_princesses.track_id%TYPE) RETURN pop_princesses.artist_name%TYPE; -- -- Global variable -- g_description CONSTANT VARCHAR2(100) := 'Functions and procedures to manage the pop_princesses table'; END manage_princesses; /
Now for the body :
CREATE OR REPLACE PACKAGE BODY manage_princesses AS -- -- This function is not declared in the package header and so -- is PRIVATE - available only to other members of the package body -- FUNCTION is_artist_on_album( pa_artist_name pop_princesses.artist_name%TYPE) RETURN BOOLEAN IS l_dummy PLS_INTEGER; CURSOR c_on_album( cp_artist_name pop_princesses.artist_name%TYPE) IS SELECT 1 FROM pop_princesses WHERE artist_name = cp_artist_name; BEGIN OPEN c_on_album( pa_artist_name); FETCH c_on_album INTO l_dummy; IF c_on_album%FOUND THEN CLOSE c_on_album; RETURN TRUE; END IF; CLOSE c_on_album; RETURN FALSE; END is_artist_on_album; -- -- Now the Public Package members -- FUNCTION catfight( pa_new_artist IN pop_princesses.artist_name%TYPE, pa_last_artist IN pop_princesses.artist_name%TYPE) RETURN BOOLEAN IS BEGIN IF pa_new_artist = 'CHRISTINA AGUILERA' AND pa_last_artist = 'BRITNEY SPEARS' THEN RETURN TRUE; END IF; RETURN FALSE; END catfight; -- -- Here's our procedure - with some minor adjustments -- PROCEDURE add_princesses( pa_artist_name IN VARCHAR2, pa_track_name IN VARCHAR2) IS l_last_artist pop_princesses.artist_name%TYPE; CURSOR c_last_artist IS SELECT artist_name FROM pop_princesses WHERE track_id = ( SELECT MAX( track_id) FROM pop_princesses); e_catfight EXCEPTION; -- -- Oh look, another user-defined exception -- e_on_album EXCEPTION; BEGIN OPEN c_last_artist; FETCH c_last_artist INTO l_last_artist; CLOSE c_last_artist; IF l_last_artist IS NOT NULL THEN -- -- call the catfight function -- IF catfight( pa_new_artist => pa_artist_name, pa_last_artist => l_last_artist) THEN RAISE e_catfight; END IF; END IF; -- -- Now check to make sure the artist isn't already on the album -- IF is_artist_on_album( pa_artist_name => pa_artist_name) THEN RAISE e_on_album; END IF; INSERT INTO pop_princesses( track_id, artist_name, track_name) VALUES( pp_track_id_seq.NEXTVAL, pa_artist_name, pa_track_name); EXCEPTION WHEN e_catfight THEN RAISE_APPLICATION_ERROR( -20000, 'Cannot put '||l_last_artist||' and '||pa_artist_name ||' together. Fur will fly!'); WHEN e_on_album THEN RAISE_APPLICATION_ERROR( -20001, 'Give someone else a chance.'); WHEN OTHERS THEN RAISE; END add_princesses; -- -- And here's our get_artist function - no change here -- FUNCTION get_artist( pa_track_id IN pop_princesses.track_id%TYPE) RETURN pop_princesses.artist_name%TYPE AS l_artist pop_princesses.artist_name%TYPE; BEGIN SELECT artist_name INTO l_artist FROM pop_princesses WHERE track_id = pa_track_id; RETURN l_artist; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 'No track with this ID'; WHEN OTHERS THEN RAISE; END get_artist; END manage_princesses; /
Note that you can specify the name of the packaged procedure you're ending in the end statement.
You also need to END the package body when you're done.
Calling a packaged procedure from outside of the package, you'll need to prefix the package name to the packaged procedure you're calling. Save the following as call_package.sql :
set serveroutput on DECLARE l_artist pop_princesses.artist_name%TYPE; l_fight BOOLEAN; l_prog_loc VARCHAR2(30); BEGIN l_prog_loc := 'Start'; -- Get the value of the package variable g_description DBMS_OUTPUT.PUT_LINE( manage_princesses.g_description); -- -- find out the artist for track 6 -- l_prog_loc := 'get_artist'; l_artist := manage_princesses.get_artist( pa_track_id => 6); DBMS_OUTPUT.PUT_LINE('Track 6 is by '||l_artist); -- -- Will Lady Gaga and Sophie Ellis Bextor get on ? -- l_prog_loc := 'catfight'; l_fight := manage_princesses.catfight( pa_new_artist => 'LADY GAGA', pa_last_artist => 'SOPHIE ELLIS BEXTOR'); IF l_fight = TRUE THEN DBMS_OUTPUT.PUT_LINE('Dressing room not big enough for both of them'); ELSE DBMS_OUTPUT.PUT_LINE('Purring like kittens.'); END IF; -- -- Now let's add another track -- l_prog_loc := 'add_princesses'; manage_princesses.add_princesses( pa_artist_name => 'THE VERONICAS', pa_track_name => 'UNTOUCHED'); EXCEPTION WHEN OTHERS THEN -- Output a message indicating the location of the error and what it -- was. This is the calling program so we won't re-raise the error -- from here. -- DBMS_OUTPUT.PUT_LINE('Error at '||l_prog_loc||' : '||SQLERRM); END; /
Now run it, check that the insert as worked and then commit. Your output should be something like :
SQL> @call_package.sql Functions and procedures to manage the pop_princesses table Track 6 is by LILLY ALLEN Purring like kittens. PL/SQL procedure successfully completed. SQL> SELECT track_id, artist_name, track_name 2 FROM pop_princesses 3 WHERE track_id = ( 4 SELECT MAX( track_id) 5 FROM pop_princesses); ARTIST_NAME -------------------------------------------------------------------------------- THE VERONICAS SQL> commit; Commit complete. SQL>
Grants ( that's Permissions to you)
Whether packages, procedures or functions, it's probable that you'll want them to be available to users other than the one that owns them. You'll need to grant EXECUTE privileges on these stored program units.
Igor wants everyone to be able to use the manage_princesses package (if only so that he gets a break from all those artistic temperament), so :
SQL> GRANT EXECUTE ON manage_princesses TO public 2 / Grant succeeded. SQL>
If we now open another session as the HR user, we should be able to see the package :
SQL> conn hr/hr@xe Connected. SQL> set serveroutput on SQL> BEGIN 2 DBMS_OUTPUT.PUT_LINE(igor.manage_princesses.g_description); 3 END; 4 / Functions and procedures to manage the pop_princesses table PL/SQL procedure successfully completed. SQL>
NOTE – it's not necessarily a great idea to grant permissions to every user on the database. However, a discussion of Oracle security is a bit outside the scope of this tutorial. Suffice to say that replacing PUBLIC in the grant statement with a specific user or a role will have the effect of granting execute privileges to that user or users who have that role.
Odds and Ends
Just to wrap things up…
Things to remember
A few key points to re-emphasise :
You can pretty much use any SQL functions in PL/SQL
Explicit cursors can return multiple rows, implicit cursors should only return one row
Be careful where you put your COMMITs and ROLLBACKs
Exceptions are your friend. They tell you when something's gone wrong. They tell you what that something is.
Other stuff I've not covered here
As I said at the start, this has been more of a quick introduction to PL/SQL than a comprehensive guide. There are other posts here which may be of interest.
- File Handling
- Arrays and Bulk Binding
- Ref Cursors
- Overloading package procedures
- Compound Triggers (from Oracle 11g)
PL/SQL can also be pretty handy when used in conjunction with Oracle's Data Dictionary Views. There are a couple of examples here and here ( this is the definitive "Killer App").
Further Reading
There's loads of information available about Oracle in general, and PL/SQL in particular. Here's just a few places you can find some useful stuff :
The Oracle documentation is freely available online.
There's lots of good stuff about individual Oracle PL/SQL commands and utilities at the PSOUG site.
Steven Feuerstein is generally regarded as the foremost authority on all things PL/SQL. He also says stuff I agree with occasionally, so I guess he knows what he's talking about.
Last, but by no means least, there is my nemisis – Tom Kyte ( long story, have a look here if you really want to know).
I'm not saying which one of us is the good one, but only one of us has been photographed sporting anything approaching a goatee !
That obscure Star Trek reference would seem to be a suitable point to end. If you have any problems…and you still think I know what I'm talking about after reading this, feel free to get in touch.


text:
LAS VEGAS — Not all the news from USA Basketball's blowout win over the Dominican Republic in their exhibition opener Thursday night at UNLV was good news.
As the U.S. players made their way from the locker room after the game, word spread Los Angeles Clippers All-Star forward Blake Griffin, who went home earlier in the day with a sore left knee, was diagnosed with a torn left meniscus and will require surgery early next week, per The Los Angeles Times. He is expected to miss eight weeks, costing him his spot on the Olympic team and putting a huge scare into the Clippers, who signed him to a five-year extension worth $95 million, just two days ago.
No one took the news harder than Griffin's All-Star teammate Chris Paul, who was informed of the news as he walked up to the assembled media awaiting the team as they exited the locker room.
"Wow. That's a tough one. It's a huge blow," Paul said. "One of the things I was looking most forward to in this whole Olympic experience was being with him, so we both could grow a little bit as players and things like that. But his health comes before anything, so I'm going to go call him and check on him."
Griffin joins a long list of U.S. stars who will miss the games due to injury, a group that already included Dwight Howard, Dwyane Wade, Chris Bosh, Derrick Rose, Chauncey Billups and LaMarcus Aldridge.
Hornets rookie Anthony Davis filled in for Griffin Thursday night and as an alternate might be tabbed to replace Griffin permanently, though there was no official word from USA Basketball after the game. Davis can't officially replace Griffin until Griffin formally withdraws from the team.
Davis looked good in his debut, scoring eight points, including a four-point play, in just 10 minutes, all in the fourth quarter, of the 113-59 win.
"I haven't heard anything other than I'm still an alternate," Davis said. "No one has told me anything different."
USA Basketball chairman Jerry Colangelo said that Davis is the only candidate they are looking at to replace Griffin on the 12-man roster.
"He's such a terrific kid. He has certain qualities that you just never know," Colangelo said. "In a game situation, he might be called upon to do something. But he's not a replacement for Blake. They are two different kind of players. Blake gave us size and strentgh and experience, obviously, and you just move on."
Word spread quickly among the players that their ranks were being thinned by injury once again, just 17 days before they open the competition in London against France.
"You have to take that news very hard," LeBron James said. "Blake's a hard worker, one of the best young players we have in this league and you never want anyone to be injured. I wish him the fastest recovery."
With the injury toll piling up the way it has, concerns about players staying healthy is no doubt going to be a hot topic among owners and players as summer league action heats up here and international exhibitions take place all over the globe.
"That only comes up when somebody gets hurt," James said. "Honestly, you could get hurt doing anything. You could get hurt working out in the summer time. It sucks for him and it sucks for everyone that's been hurt. You never want that to happen, especially in the summer time and like I said, I just wish him a fast and speedy recovery."


text:
All posts tagged "Thursday 14th February 2019"
Valentine's Kaiseki Menu at The Westin Grande Sukhumvit, Bangkok – Thursday 14th February 2019January 31, 2019
Be my Valentine at Mango Tree on the River at Yodpiman – Thursday 14th February 2019January 25, 2019
Valentine's Day at MOJJO Rooftop Lounge & Bar – Thursday 14th February 2019January 24, 2019
Valentine's Day : Seafood Set Platters at HI-SO – Thursday 14th February 2019January 14, 2019
Valentine's Day : 6-course Dinner at Park Society – Thursday 14th February 2019January 14, 2019
may, 2019
06feb(feb 6)00:0031dec(dec 31)23:59New Flavours at Trader Vic's at Anantara Riverside Bangkok ResortChef Manuel Gastelum launches Trader Vic's new menu for a new year, with an exotic medley of Pacific Rim flavours.
01mar00:0031may(may 31)23:59Mango Madness at The Eatery Four Points by Sheraton BangkokThe Eatery at Four Points by Sheraton Bangkok, Sukhumvit 15 invites all mango lovers to experience a 4 highlights of 'Mango madness' menu made from Nam Dok Mai mango Mango, a gold-yellow fruit with a delicious sweet taste and unique aroma.
03mar(mar 3)11:3029dec(dec 29)15:30Every Sunday Penthouse Brunch at Park Hyatt BangkokMake Penthouse Brunch the highlight of your Sunday and immerse in a one-of-a-kind brunch experience above the city.
15mar(mar 15)00:0030jun(jun 30)23:59Friday Night is Thai Night at Trader Vic's Anantara Riverside Bangkok ResortUnwind after work overlooking the river and start your weekend in style. Trader Vic's tropical hideaway is transformed by the spices of Thailand each Friday evening from 5 pm. Available from 15 March – 30 June 2019.
17mar(mar 17)12:0029dec(dec 29)15:00Sunday Brunch at NEXT2 Café, Shangri-La Hotel, BangkokSunday Brunch at NEXT2 Café is packed with wonderful flavors awaiting your indulgence. Enjoy some quality time with your loved ones.
19mar(mar 19)00:0031may(may 31)23:59Snack Box by Design Four Points by Sheraton BangkokMade your day successfully with customized snack box delivered straight to your meetings, events and parties from Four Points by Sheraton Bangkok, Sukhumvit 15.
20mar(mar 20)14:2030jun(jun 30)14:20Weekday Lunches at Benihana Anantara Riverside Bangkok ResortAnantara Riverside Bangkok Resort brings the world-famous flair of Benihana to the riverside. And with an express set lunch now on offer, experience all the theatrics during a business meet-up or quick weekday gathering with friends. Available form now until 30th June 2019.
31mar(mar 31)12:3029dec(dec 29)16:00Glamorous Black & White Sunday Brunch at Siam Kempinski Hotel BangkokCome celebrate a leisurely afternoon indulging in gourmet delights, caviar tasting, Blanc de Blancs champagne and smooth jazz at Brasserie Europa one of Bangkok's best brunch places.
05apr(apr 5)18:0030jun(jun 30)22:30Prime Time @ Rossini's, Sheraton Grande Sukhumvit, A Luxury Collection Hotel, BangkokEnjoy premium quality dry aged Australian beef with wines from Wine Spectator awarded primoVino by Rossini's.
14apr(apr 14)12:0005jan(jan 5)15:30Gourmet Sunday Brunch with Unlimited Lobster at The Athenee Hotel, a Luxury Collection Hotel, BangkokA special seafood selection sumptuous spring vegetable salads, splendid carvery, plus grills, foie gras and more live stations, enhance the array.
18apr(apr 18)18:3026dec(dec 26)22:30Along the Silk Road Night at Shangri-La Hotel, BangkokTake the venture along the Silk Road on every Thursday night at Shangri-La Hotel, Bangkok's NEXT2 Café.
26apr(apr 26)10:0031jul(jul 31)22:00From Monet to Kandinsky at River City BangkokRiver City Bangkok is proud to bring the works of Europe's most recognized modernist painters to Bangkok, the first time in Asia.
30apr(apr 30)10:0002jun(jun 2)20:00Thailand Mobile Expo at Bitec BangnaThailand Mobile Expo, the leading mobile exhibition in Thailand. There you will find latest technologies for smartphones, tablets, gadgets and other IT accessories.
03may(may 3)11:3007jun(jun 7)22:00Rice Dumpling Festival 2019 at Shangri-La Hotel, Bangkok"Rice Dumpling Festival" also known as "Dragon Boat Festival" is an occasion that family's members will be reunified to celebrate and praise for their antecedents.
18may(may 18)12:3029jun(jun 29)15:00New Saturday Brunch Special at ScaliniNew Scalini Saturday Brunch features Mediterranean dishes such as Galician kraken, butterfly Boston lobster, and fresh sea urchins.
23mayalldayPirates and cross dressing on the Twelfth NightTwelfth Night is a classic Shakespearian comedy that dared to question gender norms long before it was fashionable.
23may(may 23)08:0002jun(jun 2)23:00CORONADO & KONA Tap takeover Summer Beer Fest at Craft Sukhumvit 23Craft beer distributor Smiling Mad Dog will take over the taps at CRAFT Sukhumvit Soi 23, featuring 12 beers from the Coronado and Kona brewing companies for Summer Beer Fest, May 23-26.
26may(may 26)12:0016jun(jun 16)15:30Happy Father's and Mother's Day at So Sofitel BangkokMes parents Je Vous Aime Happy Father's and Mother's Day at So Sofitel Bangkok
27may(may 27)11:0031(may 31)20:00Wedding Speed Date at W BangkokW Bangkok Hotel and The House on Sathorn WEDDING SPEED DATE offers a special offer for wedding ceremonies
29mayalldayAll Women's Combined Ladies Lunch at Siam Kempinski Hotel BangkokOn Weds 29th May at 10am in the morning at the Siam Kempinski Hotel in Bangkok the All Women's Combined Ladies Lunch will be held.
30mayalldayThe Hope Fair Summer edition 2019 at Rembrandt Hotel & Towers BangkokThe Hope Fair is a socially responsible day of shopping extravaganza with no entrance fee presenting more than 100 artisans and entrepreneurs who all donate to the kids of the slums of Klongtoey.
30may(may 30)09:0002jun(jun 2)21:00Thailand Game Expo 2019 at Bitec BangnaThe biggest gaming and gaming event Bringing the most excellent device, value package and a full tournament for eSports.
31may18:0022:00Robert Mondavi Wine Dinner at The Landmark Bangkok HotelWine Journey RIB ROOM & BAR Steakhouse Outstanding wines from the celebrated winery of Robert Mondavi in California
31may18:0020:00Italian Organic Wine Journey – The Bakery at The Athenee Hotel, a Luxury Collection Hotel, BangkokThis month's Wine Journey takes place at The Bakery and will feature five different organic and biodynamic wines from Italy.


text:
It starts with a single sneezing co-worker. No matter how hard you may try to avoid him, you're trapped together in an airless office with doorknobs, light switches, copy machine buttons and water cooler spigots to pass on the germs. How do you keep from getting sick at work? These sanitary workplace and cold avoidance tips can help keep you from catching the bug.
Keep your hands clean, and avoid touching your face. It's all too easy to touch something in the workplace that may have also been touched by a person carrying the germs that cause colds and flu. Wash your hands regularly throughout the day in hot water, and fight the urge to put your fingers near your eyes, nose and mouth.
Avoid close contact with people who are ill. Sick people do often come in to work. Try not to sit too close or stand within three feet of someone who is displaying symptoms of illness, like congestion and coughing.
Clean communal areas. You may want to discreetly clean any surfaces that you know ill people have touched with an antibacterial wipe before you touch them yourself. Pay special attention to communal areas like the bathroom and kitchen, wiping down sink knobs, toilet handles, stall locks, cabinet pulls, the refrigerator door handle and buttons on the microwave. A sanitary workplace is one of the most important elements of cold and flu avoidance.
Disinfect your personal work space. Telephones, drawer handles and particularly computer keyboards can be hotbeds of germs, just waiting to catch you when your immune system is low. Keep your personal area clean and your co-workers may follow your example.
Don't use antibacterial products too often. It's tempting to go overboard with antibacterial gels and hand wipes, but using these products on a regular basis can actually make you more susceptible to colds and flu. You need regular exposure to germs in small amounts so that your body can work up a strong immune response.
Avoid communal foods. Cold and flu season coincides with the holiday season, when bowls of communal snacks like cookies, candies and dips are common. Bring your own snacks to munch on, just in case your co-workers aren't being careful about washing their hands or accidentally double-dip into that jar of nacho cheese.
Load up on vitamins and drink lots of water. Take extra vitamin C and zinc, and consider supplements like immune-boosting echinacea and bacteria-busting goldenseal. Drinking lots of water, juice, broth and other healthy fluids will help flush germs out of your system before they can make you sick, and thins the mucus that protects sensitive membranes in your eyes, nose and mouth.
Keep your stress levels down. It's easier said than done, especially this time of year, but try to get plenty of sleep and work anxiety-reducing activities like walking, yoga, reading and watching movies into your schedule. Whenever you're feeling stressed, take a few minutes to breathe deeply and cool down a bit.
Consider a flu vaccination. The Centers for Disease Control and Prevention (CDC) recommends a yearly flu vaccine as the first line of defense against influenza, offering both a live, active dose that is inhaled through the nostrils or an inactive (killed) dose for patients with weakened immune systems of long-term health problems. The flu vaccine does have side effects, but it's important to remember that influenza can be deadly: 115 U.S. children and teens died from it last flu season, and most of them had not been vaccinated.
Have other ideas for how to maintain a sanitary workplace? Leave us a note in the comments below.
MNN homepage photo: iStockphoto


text:
The Fuel Tax Evasion Unit is intended to promote compliance with fuel tax laws by providing important information about the laws, by increasing awareness of fuel-fraud schemes and by allowing online reporting of suspected fraud or other noncompliance.
Illegal/untaxed fuel is everyone's problem. It damages vehicle engines, gives violators an unfair price advantage, pollutes the air and soil due to high sulfur content, and robs funding intended for road construction.
Please report the violation if you are aware of attempts to
You can report violations by going online or calling 877.AZFuels (877.293.8357).
Arizona statute prescribes both civil and criminal penalties for violations of the fuel tax laws and related offenses. Civil penalties are in addition to any taxes and interest due and may include a penalty of 50 percent of the tax assessed if any part of the deficiency is due to fraud.
Criminal violations include those involving fuel tax evasion; impeding or obstructing enforcement of the laws; illegally using (or assisting another in using) dyed fuel on a highway; attempting to remove or alter the strength or composition of dye contained in fuel; and the filing of false statements or reports, including false claims for tax refunds. Willful violations may result in imprisonment.
The Arizona tax on gasoline (motor vehicle fuel) is 18¢ per gallon. Use fuel (diesel) is taxed at two rates in Arizona.
Note: ADOT is not responsible for regulating the proper measurement (fuel volume) of motor fuels (gasoline, diesel, propane, etc) or for analyzing fuel octane levels. If you feel that a fuel pump is not dispensing the indicated volume of fuel, or that fuel fails to meet octane standards, you should contact the Weights and Measures Division of the AZ Department of Agriculture. Also note that the state of Arizona does not regulate the price of fuel.
Arizona Department of Transportation
Contact Us
Copyright © Arizona Department of Transportation – All rights reserved.


text:
COOK Report for November - December 2015
Executive Summary
During 2015, advertising on mobile networks has come to be seen as such a gold mine that, according to an October 1 story in the New York Times, ads electronically delivered were costing users more in connect time than the network content for which they were paying in the first place. ARCH ECON members surveyed this scene and complained of an economic feudalism where companies like Google, Apple, Facebook, and Microsoft had developed ecosystems that users were forced to declare their allegiance to in a manner similar to having to pick a feudal overlord. Bruce Schneier first used the feudalism metaphor in a commentary for Wired in 2012.
These companies were offering free services, in exchange for user's data trails, while in many cases, the argument was made that users did not realize the value of what they were giving up. Doc Searles and Matt Larsen strongly agreed with and complained about the feudal metaphor. Jeff Michka noted the way in which user activities were gathered and criticized the outcome as the government permitting uncompensated "taking". Bob Atkinson agreed with Jeff and together the two came up with a strategy, with a strategy similar to network neutrality by means of which the public might be educated in such a manner as to insist on real monetary compensation for its data.
Automating the selling process through varied algorithms and tracking mechanisms has helped to create an entire industry referred to as "adtech" where judging the quality - if any - of what was going on was very difficult. Again people were asked to trust black box algorithms. And, as with email, the use of the technology on the Internet seems to be almost cost free. Only it wasn't really because no one seemed willing to deal with the fact that there was probably only a finite amount of money out there to be spent either for surveillance marketing or for the better thought-out and more graceful forms of brand marketing that companies like Apple became expert at.
In 2014-2015 with the convergence of mobile data and ubiquitous applications tied to GPS systems, the drumbeat was raised to indicate that a whole new level of advertising approach had to be adopted for: the goal of reaching people in real-time on their cell phones. As the New York Times October 1 feature explained, in the context of dealing with the pressure for quarterly results, ignoring the situation that ads tied directly to user's mobile phones had its own problems. Namely, if these ads were not completely re-crafted to deal with smaller screen sizes and load times, the players involved would likely face situations where major content sites could make strategic mistakes like that was made by boston.com. In this case, the cost that the user would have to pay to load advertising and, worst of all, tracking scripts was significantly greater than the cost of the content that presumably was the reason for the user being on the site in the first place. The result was a new kind of pollution somewhat similar to email spam where it became a natural defense of the user's monetary interests to install blocking software to render merchant attempts at surveillance marketing worthless.
In an interview, Don Martí explains how a standards free-for-all enabled a situation where, with one-pixel cookies, tracking of a user's web visits became virtually cost free and extraordinarily easy. This created a wild West kind of situation where third parties could come in and say to the more legitimate predecessors "you better buy ads from us as well or we will trash your claims to veracity." In the absence of any kind of policing mechanism, it seems that the whole advertising universe on which Internet profits depend has become unreliable. By unreliable we mean not verifiable. The sheer numbers of ad-tech companies claiming their own secret sauce, given the overall size of advertising budgets, indicate an unsustainable mechanism. Yet: when and where and what will trigger the inevitable collapse seems to be anyone's guess.
Finally, during the last two years, as pay walls have gone up around the content of everything except the homepage of the world's major newspapers and most important magazines, industry players have noted that there are a lot more page views that can be made subject to advertising. With the new technology, the question has become how to convince players whose experience has been in the form of print media to invest in the immediacy of the online space. The result has been an explosion in what is known as the Ad Tech market. The funding needed to put together companies that can promise advertisers, via black box algorithms, a secret sauce for the success of their advertising is not very great. As a result, in part three, we take a very superficial look at a few of the hundreds of new companies making up this space. In doing so, we leave it to our readers to decide whether they would put any faith in the Rube Goldberg design of IBM's Big Data Distillery.
The patience of the industry's customers is being abused. This is not a good way to build a sustainable future business model. Ad blockers are said to be relatively easy to write and there is beginning to be some evidence that the numbers of them in use are approaching the numbers of spam filters. This is not a healthy situation.
Executive summary p. 3
Introduction p. 5
Welcome to Feudalism p. 7
The Cloud as the WalMartization of Data p. 9
Computer Scientists Find Bias in Algorithms p.11
What if the Advertising Bubble Bursts? p. 13
Computer Scientists Find Bias in Algorithms p. 14
Internet Advertising Based Business Model Is in
Trouble in View of these Privacy Issues p. 28
Part 2: Interview with Don Marti p. 35
Browsers Handling of HTTP Cookies p. 36
Part 3: AdTech Developments p. 42
Conclusion p. 44


text:
Man uses stun gun on wife over football bet
JUNEAU, Wis. (AP) — A suburban Chicago man was fined $250 after being accused of using a stun gun on his wife after she lost a bet on a Packers-Bears game.
Forty-two-year-old John Grant of Tinley Park, Ill., pleaded no contest to disorderly conduct in a Wisconsin court on Thursday.
The couple was driving through Mayville when they stopped at a bar to watch the Nov. 4 game. The Bears won 27-20.
According to the complaint, Nicole Grant said her husband could use a stun gun on her for three seconds if Green Bay lost.
John Grant allegedly used it three times, and she called police. She told officers she didn't think her husband would actually use the weapon on her.