home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / answers / sybase-faq < prev    next >
Internet Message Format  |  1993-10-18  |  137KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!news.kei.com!ddsw1!meaddata!news
  2. From: davidp@meaddata.com (David Pledger)
  3. Newsgroups: comp.databases.sybase,comp.databases,comp.answers,news.answers
  4. Subject: comp.databases.sybase Frequently Asked Questions (FAQ)
  5. Supersedes: <sybfaq_748286795@meaddata.com>
  6. Followup-To: comp.databases.sybase
  7. Date: 18 Oct 1993 14:49:54 GMT
  8. Organization: Strategic Data Systems, Dayton, OH
  9. Lines: 3203
  10. Approved: news-answers-request@mit.edu
  11. Distribution: world
  12. Expires: 1 Dec 1993 14:49:50 GMT
  13. Message-ID: <sybfaq_750955790@meaddata.com>
  14. NNTP-Posting-Host: ibis.meaddata.com
  15. Summary: This monthly posting contains a list of Frequently Asked Questions 
  16.          about the Sybase Relational Database Management System (RDBMS).
  17. Keywords: Sybase,RDBMS,FAQ,Frequently Asked Questions,isql,T-SQL
  18. Xref: senator-bedfellow.mit.edu comp.databases.sybase:3698 comp.databases:29845 comp.answers:2343 news.answers:13686
  19.  
  20. Archive-name: sybase-faq
  21. Last-modified: 1993/09/16
  22. Version: 1.2
  23.  
  24. ======================================================================
  25.                            S Y B A S E
  26.  
  27.      F R E Q U E N T L Y    A S K E D    Q U E S T I O N S
  28.  
  29.  
  30.                            Version 1.2
  31.  
  32.  
  33.  
  34.  Copyright 1993 by David W. Pledger, All rights reserved.
  35. ======================================================================
  36.  
  37.    
  38. Table of Contents
  39. ======================================================================
  40. 1. Introduction
  41.    1.1.  General Information
  42.    1.2.   Summary of changes
  43.    1.3.   Posting Hints
  44.    1.4.   Archive information
  45.    1.5.   Acknowledgments
  46.    1.6.   Terms and Abbreviations
  47.    1.7.   Sybase Corporate Information
  48.        Q1. How can I get in touch with Sybase?
  49.        Q2. Who are my local user groups and how can I get in touch with
  50.           them?
  51.  
  52. 2.  Database Server
  53.  
  54.    2.1.  General Questions
  55.        Q1. What periodicals exist for Sybase?
  56.        Q2. What's a good book about Sybase?
  57.        Q3. Does Sybase support the X/Open XA interface?
  58.        Q4. Does Sybase support ODBC (Microsoft Windows Open Database
  59.           Connectivity)?
  60.        Q5. What are some of the size limitations of Sybase?
  61.  
  62.    2.2.   Sybase ISQL
  63.        Q1. How do I prevent isql output from wrapping around at 80
  64.           columns?
  65.        Q2. How do I send isql output to a file? The -o switch doesn't
  66.           work?
  67.        Q3. Can I submit a multiline statement as input to isql without
  68.           creating a file with the commands in it first?
  69.        Q4. How do I prevent the password from being displayed when
  70.           someone does a UNIX *ps* command?
  71.        Q5. I want to add some new features to isql. Does anyone have
  72.           the source code?
  73.  
  74.    2.3.   Sybase Transact-SQL
  75.        Q1. What exactly do sp_primarykey, sp_foreignkey, and
  76.           sp_commonkey do?
  77.        Q2. I want to write a new system stored procedure that gives me
  78.           information not provided by the existing stored procedures. How
  79.           do I make these available to all users like the system stored
  80.           procedures?
  81.        Q3. How can I do a "row level select" (built-in "if" function)
  82.           without having to create a temporary table, etc.?
  83.        Q4. How do I use a table name as a parameter to a stored
  84.           procedure, which will then run a query on the specified table?
  85.        Q5. Can you change the definition of a table to prohibit nulls
  86.           once you've defined it to permit them?
  87.        Q6. Is there a simple way to solve the Sybase ""matching
  88.           quotes"" requirement in a character field?
  89.        Q7. How can I do a case-insensitive search?
  90.        Q8. How do wildcards used for pattern matching work in the
  91.           context of the LIKE operator?
  92.        Q9. How do I put a unique serial number on a table?
  93.        Q10.Exactly when does a trigger fire?
  94.        Q11.Is there an easy way within the server to determine how many
  95.           days are in the current month?
  96.        Q12.How can I recursively retrieve the rows in a bill of
  97.           materials type problem?
  98.        Q13.What mechanism does Sybase offer to control concurrency when
  99.           multiple users are doing *select - think - update* kind of
  100.           operations?
  101.        Q14. In what order are defaults, rules, triggers, etc.
  102.           enforced/executed?
  103.  
  104.    2.4.   Sybase Bulk Copy
  105.        Q1. When using BCP to copy a database, is the copy equivalent to
  106.           the original in terms of performance?
  107.        Q2. Can BCP load null dates?
  108.  
  109.    2.5.   Sybase Backup and Recovery
  110.        Q1. How can I dump more than one database to a single tape?
  111.  
  112.    2.6.   Upgrading the Sybase Server
  113.        Q1. I'm upgrading from version <x> and/or operating system <p>
  114.           to version <y> and/or operating system <q>. Any advice?
  115.  
  116.    2.7.   Sybase Security
  117.        Q1. What different mechanisms are there to control Sybase
  118.           security?
  119.  
  120.    2.8.   Sybase Database Administration
  121.        Q1. Why does the transaction log on the model database keep
  122.           filling up?
  123.        Q2. Why does my transaction log fill up even when I have
  124.           allocated lots of space for it?
  125.        Q3. Is there a way to turn off logging altogether? How about
  126.           putting the transaction logs on `/dev/null'? How does tempdb
  127.           avoid logging?
  128.        Q4. Is there any reason not to have `truncate log on checkpoint'
  129.           turned on for the model database?
  130.        Q5. Why doesn't the Sybase kill command work?
  131.        Q6. What are some of the undocumented features of DBCC?
  132.        Q7. Why don't the dbcc commands produce any output on my screen?
  133.        Q8. What are the trace flags used for and what are some of the
  134.           more common flags?
  135.        Q9. Is there a way to accurately estimate how much space a table
  136.           and its indexes are going to take?
  137.        Q10.What causes a database to be marked SUSPECT and can I
  138.           recover a database that comes up marked `SUSPECT'?
  139.        Q11.My database tables often get locked by the client's hung
  140.           workstation. Is there a way that I can unlock those locked
  141.           tables?
  142.        Q12.Does the server sort order affect performance? Is binary
  143.           sort order the fastest way?
  144.        Q13.Does Sybase have a memory limit?
  145.  
  146.    2.9.   Sybase Performance Tuning
  147.        Q1. How much overhead do variable size and NULL columns require?
  148.        Q2. How are null values stored?  How does Sybase distinguish
  149.           between an integer and a null value for an integer, and so forth?
  150.        Q3. How are text and image types stored?
  151.        Q4. How do I interpret the cryptic output of 'set showplan on'?
  152.        Q5. How does the query optimizer work? Does the ordering of
  153.           tables in the from clause or the conditionals in the where
  154.           clauses affect the performance of the query?
  155.        Q6. Can I force the optimizer to access tables in a certain
  156.           order or to use a particular index?
  157.        Q7. Does dropping an index cause recompilation of a stored
  158.           procedure?
  159.        Q8. Does the time for a select that yields 1000 rows from a
  160.           table of 10,000 differ much from the same select when the table
  161.           contains 100,000 rows?
  162.        Q9. Is there a way to gather performance statistics besides
  163.           using sp_monitor?
  164.        Q10.Does Sybase do page or row level locking?
  165.        Q11.What types of locks can be issued and what do they mean?
  166.        Q12.What exactly does the HOLDLOCK keyword do?
  167.        Q13.Why, when a stored procedure is forced to compile, does the
  168.           query plan grow eventually causing the stored procedure to crash?
  169.        Q14.What is a segment and why should I use one?
  170.        Q15.What determines whether an update will be performed 'in
  171.           place' or deferred?
  172.        Q16.How does altering a database table to add a new column
  173.           affect the storage of the affected table?
  174.        How do I delete a column from a table?
  175.  
  176.    2.10.  Sybase Network Issues
  177.        Q1.How can I make Sybase talk to two separate ethernet
  178.           interfaces on our server?
  179.        Q2.Can I use Sybase over PPP (Peer-to-Peer protocol)?
  180.  
  181. 3. Sybase Core Applications
  182.  
  183.    3.1.   Open Client
  184.        Q1. Has anyone implemented a C++ class library for Sybase?
  185.        Q2. How can I use the Sybase Open Client with my C++ code?
  186.        Q3. Which C compiler(s) is the DOS version of the Open Client
  187.           software compatible with?
  188.  
  189.    3.2.   Open Server
  190.  
  191.    3.3.   APT
  192.        Q1. Is it possible to place other visible fields on top of
  193.           invisible fields, or do I have to have big open spaces?
  194.  
  195.    3.4.   DWB
  196.  
  197.    3.5.   Report Writer
  198.        Q1. How can I load the reports into a production db in a batched
  199.           (non-interactive) way?
  200.  
  201.    3.6.  Gain Momemtum
  202.  
  203. 4.  Third Party Applications
  204.  
  205.    4.1.   User Interface/Client Applications
  206.        1. JYACC JAM/DBi
  207.        2. Uniface
  208.        3. Power Builder (Microsoft Windows only)
  209.        4. Microsoft Access/Visual Basic
  210.        5. DataEase
  211.        6. Unify
  212.        7. Focus
  213.        8. ObjectView
  214.        9. Q+E
  215.        10.Superbase
  216.        11.R&R Report Writer for Windows, SQL Edition
  217.        12.CorVu
  218.  
  219.    4.2.   Class Libraries
  220.        1.  DBh++
  221.        2. C++ API
  222.        3. Persistence
  223.  
  224.    4.3.   Other Miscellaneous Products and Tools
  225.        1.  SybPERL
  226.        2. SQL-BackTrack
  227.        3. dbViewer
  228.        4. Xsybmon
  229.        5. Sybtcl
  230.    
  231. ======================================================================
  232. 1. Introduction
  233.  
  234. ----------------------------------------------------------------------
  235. 1.1.    General Information
  236.    
  237.    This document is copyrighted.  Compiling and refining this document
  238.    monthly requires a significant effort on my part.  My main reason for
  239.    copyrighting this document is to protect my sweat-equity and be given credit
  240.    for this effort.  Copy and distribute this document freely under these three
  241.    guidelines:  (1) Include my name, the copyright notice, and this paragraph in
  242.    all reproductions.  (2) Do not under any circumstances distribute this
  243.    document for profit.  (3) Do not publish this document or any portion of this
  244.    document in any journal, trade publication, etc. without my prior written
  245.    consent.  I do not guarantee or warrant that information contained in this
  246.    document is accurate.
  247.    
  248.    The intent of this document is to answer many of the frequently asked
  249.    questions about the various products that Sybase offers. The emphasis of this
  250.    FAQ is on the database server, primarily because that is my expertise. I will
  251.    include questions and discussion on Open Server, Open Client, and other
  252.    topics as I receive pertinent information.
  253.    
  254.    There are undoubtedly typos, mistakes, and other misinformation which I am
  255.    certainly trying my hardest to eliminate.  Comments and corrections are
  256.    welcomed and encouraged.  Please direct all comments to davidp@meaddata.com.
  257.    Include the phrase `Sybase FAQ' as the subject of your message. I will
  258.    include your changes as appropriate and give credit where credit is due.
  259.    As an added bonus, I will add you to a mailing list to automatically
  260.    receive future releases of this document as soon as it is available if
  261.    you provide any new information or corrections.
  262.    
  263.    This article is posted to the news group comp.database.sybase monthly. This
  264.    article is also cross-posted to news groups news.answers, comp.databases, and
  265.    comp.answers.
  266.    
  267.    Please send me a note if you have any particular topic you would like to see
  268.    addressed or any comments on the content or organization of this document.
  269.  
  270. ----------------------------------------------------------------------
  271. 1.2.     Summary of changes
  272.    
  273.    This is the Sybase FAQ, version 1.2. This supercedes version 1.1 issued in
  274.    mid September, 1993.  
  275.  
  276.    As you can see, I have once again reorganized the document in an attempt 
  277.    to find the best presentation.  (All of this change will stop when you 
  278.    see release 2.0.)
  279.  
  280.    My appologies for all those individuals who provided information that 
  281.    didn't make it into the FAQ.  It has been a busy month.  I will 
  282.    include it in the next release (In particular, the client applications 
  283.    have been changed very little).  I'll also divide this FAQ into multiple
  284.    parts next time since it is getting a little too large.
  285.    
  286.    This is a living document and is still in its infancy.  There are significant
  287.    changes each month, so I will not attempt to list them at this time. As the
  288.    document becomes more stable, I will include a detailed list of changes.
  289.  
  290. ----------------------------------------------------------------------
  291. 1.3.     Posting Hints
  292.    
  293.    Before posting to comp.databases.sybase, please consider that many people in
  294.    Netland are reading News using an 80 column display. If you set your right
  295.    margin to 75 it will make your article much easier to read for those people.
  296.    
  297.    You may want to refer to the newsgroup news.newusers.questions for
  298.    translations of IMHO, IMO, BTW, wrt, 8-), etc.
  299.  
  300. ----------------------------------------------------------------------
  301. 1.4.     Archive Information
  302.    
  303.    This FAQ is archived at the ftp site: straylight.acs.ncsu.edu:/pub/sybase
  304.  
  305. ----------------------------------------------------------------------
  306. 1.5.     Acknowledgments
  307.    
  308.    The following individuals have made significant contributions toward the
  309.    compilation of this document.  I have received many usefule comments
  310.    from individuals at Sybase that have greatly improved to content
  311.    and accuracy of this document.  Many thanks to all of you!
  312.    
  313.    Name                     Email Address
  314.    ----------------------   ---------------------------
  315.    David Pledger            davidp@meaddata.com
  316.    Ben von Ullrich, Sybase
  317.    Howard Michalski, Sybase
  318.    Elton Wildermuth, Sybase
  319.    Tom Warfield             vnunet!twarfield
  320.    David Joyner             nsysdbj@acs.ncsu.edu
  321.  
  322. ----------------------------------------------------------------------
  323. 1.6.     Terms and Abbreviations
  324.    
  325.    The following list contains terms and abbreviations that are used within this
  326.    document.
  327.  
  328.         APT - Application Programming Toolkit (Sybase Product)
  329.         dbid - Database Id
  330.         DDL - Database Definition Language (SQL Create & Index Statements)
  331.         DML - Database Manipulation Language (SQL Insert, Update, Delete, &
  332.         Select)
  333.         DSS - Decision Support Systems
  334.         DWB - Data WorkBench (Sybase Product)
  335.         EBF - Emergency Bug Fix
  336.         Gain Momentum - a multimedia tool that supports audio, video, animation,
  337.         and is a front-end to SQL databases. (Sybase product)
  338.         GAM - global allocation map
  339.         indid- Index Id
  340.         LFS - logical file system
  341.         LRU - least recently used
  342.         OAM - Object Allocation Map
  343.         OLTP - On Line Transaction Processing
  344.         objid - Object Id
  345.         PSS - Process Slot Structure
  346.         Rid - Row Id
  347.         Rollup - Collection of bug fixes issued as an upgrade release.
  348.         SPID - Server Process Id
  349.         sproc - Stored Procedure
  350.         SQR - Structured Query Report Writer (Sybase Product)
  351.         STS - Sybase Technical Support
  352.         T-SQL - Transact SQL, Sybase's version of SQL with extensions.
  353.         vdevno- virtual device number
  354.    
  355.  
  356. ----------------------------------------------------------------------
  357. 1.7.     Sybase Corporate Information
  358.    
  359.    ++++++++++++++++++++++++++++++++++++++++++++++
  360.    Q1.  How can I get in touch with Sybase?
  361.  
  362.    Answer:    Sybase's main phone number for all customer inquiries
  363.    is 1-800-8-SYBASE  (1-800-879-2273)
  364.    
  365.    Europe
  366.    ---------------------------------------------
  367.    [partial list]
  368.    France          33-1-42'18'42'18
  369.    Germany         49-211-59760
  370.    Netherlands     31-3465-82999
  371.    UK         44-628-597100
  372.    
  373.    Other European inquiries  31-3465-82999 (European Headquarters)
  374.    
  375.    Canada          416-566-1803
  376.    
  377.    Japan           81-3-5280-1141
  378.    
  379.    For other Asia, Pacific, and Latin America inquiries, 510-596-3500
  380.    
  381.    Corporate Address
  382.         Sybase, Inc.
  383.         6475 Christie Avenue
  384.         Emeryville, CA 94608
  385.         Phone: 1-(510) 596-3500 (corporate headquarters)
  386.         FAX:  1 (510) 658-9441
  387.    
  388.    Dial Up Service
  389.         INSIGHT 1-510-601-4991.  To register, dial up the above number 
  390.         with your computer/modem and have you customer number (from 
  391.         any Sybase software packing list) handy.  Next time you call 
  392.         Technical Support or customer Service, ask for your contact ID.  
  393.         Only registered technical support contacts are allowed to dial in.
  394.    
  395.    Support Renewals
  396.         1-510-596-4524
  397.    
  398.    Customer Service
  399.         1-510-596-3333.  This is the main customer service line.  They can
  400.         answer or direct any non-technical, non-support renewal questions and
  401.         expedite service.
  402.    
  403.    
  404.    
  405.    ++++++++++++++++++++++++++++++++++++++++++++++
  406.    Q2.  Who are my local User Groups and how can I get in touch
  407.       with them?
  408.  
  409.    Answer:    There are a number of groups in different areas of the country,
  410.    some of which include...
  411.    
  412.         BAWASLUG: Baltimore / Washington Area Sybase Local User's Group
  413.         Meets Quarterly
  414.         Contact: Unknown
  415.         
  416.         GLSSUG:  Great Lakes SQL Server User Group.  Meets monthly.
  417.         Contact:  GLSSUG, Information Management Group, 720 N. Franklin St.,
  418.         Suite 300, Chicago, IL  60610
  419.    
  420. ======================================================================
  421. 2.  Database Server
  422.  
  423. ----------------------------------------------------------------------
  424. 2.1.    General Questions
  425.    
  426.    ++++++++++++++++++++++++++++++++++++++++++++++
  427.    Q1.  What periodicals exist for Sybase?
  428.  
  429.    Answer:    The following magazines are either Sybase specific or related to
  430.    relational database design.
  431.    
  432.         SQL Forum
  433.         PO Box 240
  434.         Lynnwood, WA 98046-0240
  435.         Phone (206)382-6607
  436.         Published bi-monthly (6 issues yearly)
  437.         us$60/year.
  438.         
  439.         Sybase Magazine
  440.         (You already get this for free if you are a customer)
  441.         
  442.         The Relational Journal
  443.         Codd & Date, Inc.
  444.         1772A Technology Drive
  445.         San Jose, CA 95110-1306
  446.         Phone: (408) 441-6400
  447.         Published bi-monthly
  448.         us$249.00/year
  449.    
  450.    ++++++++++++++++++++++++++++++++++++++++++++++
  451.    Q2.  What's a good book about Sybase?
  452.  
  453.    Answer:    Consider the following texts.
  454.         
  455.         A Guide to Sybase and SQL Server
  456.         McGoveran and Date
  457.         Addison Wesley Publishers, 1993
  458.         ISBN 0-201-55710-X
  459.         
  460.         Sybase Architecture and Administration
  461.         John Kirkwood
  462.         Ellis Horwood Publishers
  463.         ISBN 0-13-100330-5
  464.    
  465.    ++++++++++++++++++++++++++++++++++++++++++++++
  466.    Q3.  Does Sybase support the X/Open XA interface?
  467.  
  468.    Answer:    Currently, Sybase does not support the X/Open XA interface. You
  469.    cannot use it with either Encina or Tuxedo for global transaction management
  470.    in the X/Open DTP environment. System 10 is supposed to be XA complient.
  471.    However, you CAN use it with TOP END, NCR's TP Monitor. TOP END's XA Veneer
  472.    Technology allows Sybase's non-XA compliant DBMS product to participate in
  473.    global transactions in an X/Open DTP environment. This XA Veneer DOES make
  474.    use of Sybase's two-phase commit feature.
  475.  
  476.    Thanks to Ray Niety.
  477.    
  478.    ++++++++++++++++++++++++++++++++++++++++++++++
  479.    Q4.  Does Sybase support ODBC (Microsoft Windows Open Database
  480.       Connectivity)?
  481.  
  482.    Answer:    Yes, but you may need to install additional stored procedures in
  483.    the master database to get it to work.  these can be loaded with the file
  484.    "instcat.sql".  If you are running Sybase under Novell or the Microsoft SQL
  485.    Server (purchased and supported by Microsoft) these come pre-installed, but
  486.    may not be up to date.  In particular, if you are trying to use Visual Basic
  487.    as a front end, you will need to run the instcat.sql script that comes with
  488.    the Visual Basic distribution diskettes.
  489.    
  490.    ++++++++++++++++++++++++++++++++++++++++++++++
  491.    Q5.  What are some of the size and space limitations of Sybase?
  492.  
  493.    Answer:
  494.    *  Columns in a table, view, or query...................... 250
  495.    *  Tables in a view or query................................ 16
  496.           (including work tbles, which are created by
  497.            sorts and aggregrates)
  498.    *  Indexes per table....................................... 250 
  499.           ( plus 1 clustered index)
  500.    *  Columns in a composite index............................. 16
  501.    *  Maximum row size in bytes.............................. 1962
  502.           (not counting text and image columns)
  503.    *  Size of code for a query or stored procedure............ 65K
  504.    *  Memory required for a query or stored procedure......... 65K
  505.    *  Comparisons in a WHERE clause........................... 250
  506.    *  Items in an IN clause (WHERE X in (1,2,3...))........... 250
  507.    *  Parameters for a stored procedure....................... 255
  508.    *  Levels of nesting of stored procedure calls.............  15
  509.    *  Databases per server.................................. 32767
  510.    *  Tables per database............................... 2 billion
  511.    *  Rows per table............................ Available storage
  512.  
  513. ----------------------------------------------------------------------
  514. 2.2.     Sybase ISQL
  515.    
  516.    ++++++++++++++++++++++++++++++++++++++++++++++
  517.    Q1.  How do I prevent isql output from wrapping around at 80
  518.       columns?
  519.  
  520.    Answer:    Use the -w switch to specify a different width, as in
  521.    
  522.         isql -Ulogin -Sserver -w132 /* 132 character width column */
  523.    
  524.    See 'isql' in the the Utility Programs Section in the Sybase Commands
  525.    Reference manual for a detailed explanation of all command line switches.
  526.    
  527.    ++++++++++++++++++++++++++++++++++++++++++++++
  528.    Q2.  How do I send isql output to a file? The -o switch doesn't work?
  529.  
  530.    Answer:    Use the redirection symbol, ">", as in
  531.    
  532.         isql -i script.sql > results.sql
  533.    
  534.    ++++++++++++++++++++++++++++++++++++++++++++++
  535.    Q3.  Can I submit a multiline statement as input to isql without creating 
  536.       a file with the commands in it first?
  537.  
  538.    Answer:    Yes, try...
  539.    
  540.         isql -Ulogin -Ppassword >outfile_name <<EOF
  541.         use database
  542.         go
  543.         select column
  544.         from table
  545.         where condition is true
  546.         order by column
  547.         go
  548.         EOF
  549.  
  550.    This is referenced as a "here document" in most UNIX manuals. This will also
  551.    result in the password being visible by anybody happening to do a `ps'
  552.    command when the command is run.
  553.    
  554.    This method also works in DOS:
  555.         isql -Ulogin -Ppassword -i con >outfile_name   
  556.                                 /* ^^^ con stands for console */
  557.         use database
  558.         go
  559.         select column
  560.         from table
  561.         where condition is true
  562.         order by column
  563.         go
  564.         ^Z  /* Control - Z */
  565.    
  566.    ++++++++++++++++++++++++++++++++++++++++++++++
  567.    Q4.  How do I prevent the password from being displayed when someone 
  568.       does a UNIX *ps* command?
  569.  
  570.    Answer:    Depending on the version of Sybase and the port, this may or may
  571.    not already be supported. In the cases where it is not supported, several
  572.    tricks have been used.
  573.  
  574.    For those cases where the password shows up, try using the command line
  575.    options -i and -o rather than the shell redirects (< and >). This is nice
  576.    because the "Password:" prompt shows up accept your password.
  577.    
  578.         isql -U login -i input.sql -o output.out
  579.         Password: password
  580.    
  581.    You can also put the password as the first line that isql receives from
  582.    standard input.
  583.  
  584.         isql -U logins >output.out <<EOT
  585.         password
  586.    
  587.         use database
  588.         go
  589.         sp_help
  590.         go
  591.         quit
  592.         EOT
  593.    
  594.    One last alternative, thanks to Uday Shankar, is to either directly or
  595.    through an environment variable echo the password and pipe it into isql.  The
  596.    password doesn't show up with the *ps* command and the password is not part
  597.    of the isql call.  An example:
  598.    
  599.         echo "password" | isql -U<login> << EOF
  600.         use database
  601.         go
  602.         sp_who
  603.         go
  604.         quit
  605.         EOF
  606.    
  607.    ++++++++++++++++++++++++++++++++++++++++++++++
  608.    Q5.  I want to add some new features to isql. Does anyone have the source
  609.       code?
  610.  
  611.    Answer:    David Joyner at NCSU has published a shareware version, called
  612.    "dsql". It is available via anonymous ftp from
  613.  
  614.         straylight.acs.ncsu.edu:/pub/sybase.
  615.    
  616. ----------------------------------------------------------------------
  617. 2.3.     Sybase Transact-SQL
  618.    
  619.    
  620.    ++++++++++++++++++++++++++++++++++++++++++++++
  621.    Q1.  What exactly do sp_primarykey, sp_foreignkey, and sp_commonkey do?
  622.  
  623.    Answer:    They register the key relationships in syskeys. They DO NOT create
  624.    indexes and they DO NOT make Sybase automatically enforce referential
  625.    integrity. The key relationships registered in syskeys may be used by a 
  626.    front-end product to infer the logical schema.
  627.  
  628.    DWB's VQL module uses them to create joins as queries are built.  APT-BUILD
  629.    uses them in a similar fashion.  Currently, they are included to build a more
  630.    complete data dictionary, though SQL Server itself does not use them.  In
  631.    system 10, the DDL supports declared entity relationships, which are fully
  632.    supported by the relational engine.  Therefore, the need for these stored
  633.    procedures in system 10 is essentially obviated.
  634.    
  635.    ++++++++++++++++++++++++++++++++++++++++++++++
  636.    Q2.  I want to write a new system stored procedure that gives me 
  637.      information not provided by the existing stored procedures. How do 
  638.      I make these available to all users like the system stored procedures?
  639.  
  640.    Answer:    All system stored procedures MUST start with the prefix `sp_' AND
  641.    be loaded by the System Administrator in the master database. Procedures
  642.    starting with this prefix have two main properties (1) They are visible from
  643.    all databases, and (2) They switch context to the local database when
  644.    executed. For example, a reference to the sysusers table does not read the
  645.    sysusers table from the master database, but from the local database in which
  646.    the procedure is called.
  647.  
  648.    Do NOT replace any of the existing stored procedures with procedures of your
  649.    own design. Any upgrade which runs the `installmaster' script will delete and
  650.    overwrite your changes.  Making changes to Sybase-supplied procedures can
  651.    also damage your system tables and/or your SQL Server if the procedures do
  652.    not behave as other procedures and SQL Server expect them to.  Proceed with
  653.    caution.
  654.    
  655.    ++++++++++++++++++++++++++++++++++++++++++++++
  656.    Q3.  How can I do a "row level select" (built-in "if" function) without
  657.       having to create a temporary table, etc.?
  658.  
  659.    Answer:    This original solution detailed in previous versions may require a
  660.    division by zero and results in SQL errors that are avoidable.  Andrew
  661.    Zanevsky provides this alternate solution that is functionaly equivalent to
  662.    the previous solution and eliminates the divide by zero problem.
  663.    
  664.    I'm trying to create a view on a table selecting one of two fields depending
  665.    on the value of a third e.g...
  666.    
  667.         select field1 from table where field3 = 1
  668.         union
  669.         select field2 from table where field3 = 2
  670.         
  671.    If field1 & field2 are integers then this will work
  672.         SELECT field1*(1-ABS(SIGN(field3-1)))+field2*(1-ABS(SIGN(field3-2)))
  673.         FROM table
  674.         
  675.    The function
  676.         eqfn(x,y) = (1 - ABS( SIGN(x - y)))
  677.    is a function which will return 1 if x = y and 0 otherwise.
  678.    
  679.    The solution where the fields are characters is more complicated.
  680.         SELECT SUBSTRING(field1+field2,
  681.              eqfn(field3,2)*datalength(field1)+1,
  682.         
  683.         eqfn(field3,1)*datalength(field1)+eqfn(field3,2)*datalength(field2))
  684.         FROM table
  685.    
  686.    only this will return field1 if field3 is 1 and field2 otherwise. It can be
  687.    modified to return a different value if field3 is not 1 or 2.
  688.    
  689.    ++++++++++++++++++++++++++++++++++++++++++++++
  690.    Q4.  How do I use a table name as a parameter to a stored procedure, 
  691.       which will then run a query on the specified table?
  692.  
  693.    Answer:    You can't; also you can't do "dynamic queries". However, you might
  694.    want to try using sp_rename to "fool" Sybase, as suggested (although not
  695.    wholeheartedly recommended) by rthomas@hakatac.almanac.bc.ca (Robert N
  696.    Thomas) [this won't work with temporary tables, though]:
  697.    
  698.    1. Create a view of each table you will want to access as a parameter.(this
  699.       will allow other sessions to continue accessesing the tables without
  700.       interruption).
  701.  
  702.    2. Set the permissions on the views so that NOBODY can access them. Only
  703.       through the MAGIC stored procedure is access granted to the views.
  704.  
  705.    3. Figure out how to declare a section of your stored procedure as critical,
  706.       so that only one sybase process can access the below code at one time.
  707.  
  708.    4. Setup the procedure to look something like:
  709.  
  710.          CRITICAL (I forget the exact command).
  711.          sp_rename inuse, @vartable
  712.          select * from inuse
  713.          sp_rename @vartable, inuse
  714.          END CRITICAL portion
  715.    
  716.    ++++++++++++++++++++++++++++++++++++++++++++++
  717.    Q5.  Can you change the definition of a table to prohibit nulls once
  718.       you've defined it to permit them?
  719.  
  720.    Answer:    No, but you can prevent NULLs using triggers. A trigger can use
  721.    the `IS NULL' test to check if any column has a NULL value. A RULE will not
  722.    work. The rule check is NOT executed against columns that contain a NULL
  723.    value.
  724.    
  725.    ++++++++++++++++++++++++++++++++++++++++++++++
  726.    Q6.  Is there a simple way to solve the Sybase ""matching quotes""
  727.       requirement in a character field?
  728.  
  729.    Answer:    A client application program can use the dbsafestr() call, which
  730.    is part of DB-Library. This routine will double any and all quotes in a
  731.    character string, making that string "safe" for inclusion within any SQL
  732.    statement.
  733.    
  734.    In APT-SQL, the similar function is sqlexpr().
  735.    
  736.    ++++++++++++++++++++++++++++++++++++++++++++++
  737.    Q7.  How can I do a case-insensitive search?
  738.  
  739.    Answer:    There are two ways to accomplish this:
  740.  
  741.    Method 1:      Use the case-insensitive sort order.  This may be specified
  742.    during server installation or changed afterward with a bit of work.  This
  743.    affects all databases on the server and cannot be isolated to a single
  744.    database.
  745.    
  746.    Method 2:      Use the upper or lower function to equate strings for
  747.    searching.  For example,
  748.  
  749.         select col1 from table where upper(col1) = upper("string")
  750.         or
  751.         select col1 from table where upper(col1) = "STRING"
  752.    
  753.    Using the upper function in the where clause on the column name
  754.    'upper(columnname)' causes the optimizer to NOT use any index defined on that
  755.    column.  This can result in poor retrieval performance since a table scan
  756.    rather than an indexed retrieval will be performed.  Converting columns to
  757.    upper case upon insert or update is a better strategy since the data will be
  758.    physically stored in the table in upper case. The 'upper' function no longer
  759.    needs to be used on the column name and any index on that column is likely to
  760.    be used.  For example,
  761.  
  762.         select col1 from table where col1 = upper("string")
  763.         or
  764.         select col1 from table where col1 = "STRING"
  765.         
  766.    will use an index defined on col1 since col1 is physically stored in the
  767.    database in upper case.  Triggers can also be used to maintain a shadow
  768.    column of the case-sensitive (or printable) column is a uniform-case column,
  769.    e.g., last_name_lc, which is lower()ed from the last_name column value in the
  770.    table's insert and update triggers.  One last option is to use the LIKE
  771.    operator to search the column for both cases.  For example,
  772.  
  773.         WHERE last_name like "[Zz][Zz][Yy][Vv][Aa]"
  774.         
  775.    Thanks to Sorin Shtirbu, Christopher Eastman, and Ben von Ullrich
  776.    
  777.    
  778.    ++++++++++++++++++++++++++++++++++++++++++++++
  779.    Q8.  How do wildcards used for pattern matching work in the
  780.       context of the LIKE operator?
  781.  
  782.    Answer:    This is best answered with an example:
  783.  
  784.    Given that table1 contains col1 and has the values
  785.    table1
  786.    ----------
  787.    Bob
  788.    Ricky
  789.    The following query:
  790.    
  791.         select *
  792.         from table1
  793.         where col1 not like '____'  /* 4 underscores */
  794.         
  795.    will return "Ricky" and will NOT return "Bob", "Ricky"
  796.    Here's why:
  797.  
  798.    1.  ["Bob" = "Bob "] is TRUE. This is a given, since ANSI says that in
  799.       comparing two strings, the shorter string will be conceptually padded
  800.       with blanks to equal the length of the longer string before comparing.
  801.  
  802.    2. If 1 is TRUE, then ["Bob" LIKE "Bob "] is also TRUE. Otherwise, a LIKE
  803.       comparison would differ fundamentally from an EQUAL comparison.
  804.  
  805.    3. ["Bob" LIKE "___"] and [" " LIKE "_"] are both TRUE, by Sybase's
  806.       definitions of the wildcards.
  807.  
  808.    4. By 2 and 3, ["Bob" LIKE "Bob_"] is TRUE.  Therefore, ["Bob" LIKE "____"]
  809.       is TRUE, and ["Bob" NOT LIKE "____"] is FALSE. The query should NOT
  810.       return "Bob", because the string has been extended with blanks to pad it
  811.       out to the length of the "longer" (pattern) string.
  812.    
  813.    To select all names of NOT EXACTLY 4 characters, use
  814.    
  815.          NOT LIKE "[^ ][^ ][^ ][^ ]"
  816.         
  817.    This pattern string will match ONLY non-blank characters, so the query will
  818.    fail to match all strings with blanks in them ("Bob ") as well as all strings
  819.    longer than 4 characters ("Ricky").
  820.  
  821.     -- Elton Wildermuth, Sybase SQL Server Development
  822.    
  823.    ++++++++++++++++++++++++++++++++++++++++++++++
  824.    Q9.  How do I put a unique serial number on a table?
  825.  
  826.    Answer:    Michael Keirnan writes:
  827.    Create a reference table with one row (I've also heard them referred to as
  828.    surrogate id tables). Create a stored procedure called something like
  829.    get_next_id. This stored procedure increments the current id and returns, via
  830.    a parameter, the new id. This of course is done inside a transaction, and the
  831.    increment (UPDATE statement) should be done first. No trigger required. For
  832.    example:
  833.    
  834.         create table IDExamples:Surrogate Id
  835.         (NextId int)
  836.         go
  837.         
  838.         create procedure GetNextId
  839.         @SurrogateId int out
  840.         as
  841.              /* Start a transaction */
  842.              begin transaction
  843.         
  844.              /* Update the ID first to lock the table
  845.              ** and block others from changing the value.
  846.              */
  847.              update ID
  848.              set NextId = NextId + 1
  849.         
  850.              /* Safe to select, others calls blocked. */
  851.              select @SurrogateId = NextId
  852.              from ID
  853.         
  854.              /* Commit the completed transaction */
  855.              commit transaction
  856.         go
  857.    
  858.    There is an important disclaimer to this method. This approach guarantees
  859.    that all inserts into the table are single threaded and that concurrent
  860.    inserts will never happen. Each request for an ID will be blocked and wait
  861.    for any preceeding requests for an ID since the page containing the ID is
  862.    locked. This could be a bottleneck for a multi-user system.
  863.    
  864.    Now that we all know the answer, System 10 will provide the keyword
  865.    'identity' and will automatically generate surrogate IDs as required.
  866.    
  867.    ++++++++++++++++++++++++++++++++++++++++++++++
  868.    Q10. Exactly when does a trigger fire?
  869.  
  870.    Answer:    A trigger will fire once per statement affecting the table
  871.    (insert, update, and/or delete), even if NO rows are affected. It fires after
  872.    the physical table has been modified (AFTER indexes are checked and updated,
  873.    after rules are checked, after defaults are applied).  Triggers are just
  874.    about the LAST step prior to transaction commit.  Any ROLLBACK TRANSACTION
  875.    statement in the trigger will do just that:  undo all the changes made to all
  876.    table data and indexes affected by the command.  Triggers do not (until
  877.    System 10) fire recursively on the trigger table if the trigger alters its
  878.    trigger table. This gives rise to coding like:
  879.    
  880.         /* If you just want to count the number of rows in the log */
  881.         create trigger happy_trails
  882.         on the_range
  883.         for update
  884.         as
  885.         if (select count(*) from inserted) = 0 return
  886.         
  887.         -OR-
  888.         
  889.         /* @@rowcount is assigned to a variable, @rows_altered, because the if()
  890.         ** changes its value.
  891.         */
  892.         create trigger happy_trails
  893.         on the_range
  894.         for update
  895.         as
  896.         declare @rows_altered int
  897.         select @rows_altered=@@rowcount
  898.         if (@rows_altered = 0) return
  899.    
  900.    This eliminates the expense of going through later trigger code which will
  901.    have no effect. A similar method can be used if, for example, you want to
  902.    allow only one row inserted per statement.
  903.    
  904.    ++++++++++++++++++++++++++++++++++++++++++++++
  905.    Q11. Is there an easy way within the server to determine how many days
  906.       are in the current month?
  907.  
  908.    Answer:    This solution comes from Elton Wildermuth at Sybase
  909.    
  910.    Obtain the month number, M.
  911.    If (M = 2) /* February is a special case */
  912.    
  913.         Obtain the 4 digit year, Y
  914.         if   ((Y % 4 = 0) and
  915.              ((Y % 100 != 0) or
  916.              (Y % 400 = 0)))
  917.              days := 29
  918.         else
  919.              days := 28
  920.    else
  921.         if (M > 7) /* If month is after "July" */
  922.              M := M - 7 /* subtract 7 from month */
  923.         days := 30 + (M & 1)
  924.         /* Now, if month is odd, it has 31 days */
  925.    
  926.    Why this works:
  927.    
  928.     31 30 31 30 31 30 31
  929.     Ja -- Ma Ap My Ju Jy
  930.     Au Se Oc No De
  931.    
  932.    Suggestion: build this into a stored procedure, and call it; assign its
  933.    return value to a variable. Give the procedure an optional datetime param, so
  934.    that it can calculate days-in-month for a random date; let the date default
  935.    to getdate(). Example:
  936.    
  937.    create procedure get_days
  938.         @days int OUTPUT,
  939.         @date datetime=NULL
  940.    as
  941.    
  942.    declare        @m int,
  943.              @y int
  944.    if (@date is NULL)
  945.         select @date = getdate()
  946.    select @m = datepart(mm, @date)
  947.    if (@m = 2)
  948.    begin
  949.         select @y = datepart(yy, @date)
  950.         if   (@y % 4 = 0) and
  951.              ((@y % 100 != 0) or (@y % 400 = 0))
  952.    
  953.              select @days = 29
  954.         else
  955.              select @days = 28
  956.         end
  957.    else
  958.    begin
  959.         if (@m > 7)
  960.              select @m = @m - 7
  961.         select @days = (30 + (@m & 1))
  962.    end
  963.    return
  964.    
  965.    Tony Langdon offers an alternate solution to this problem, noting that the
  966.    previous solution cannot be used within a DML instruction.
  967.    select datepart(day,
  968.        dateadd(day,-1,
  969.             dateadd(month,1,
  970.                 dateadd(day,1-datepart(day,getdate()),getdate()))
  971.        )
  972.    )
  973.    
  974.    Which works as follows :
  975.    1. Get first day in current month
  976.         dateadd(day,1-datepart(day,getdate()),getdate())
  977.    2. Get first day in next month
  978.         dateadd(month,1,......)
  979.    3. Get last day in current month
  980.         dateadd(day,-1,.......)
  981.    4. Days in month
  982.         datepart(day,.........)
  983.  
  984.    One final solution provided by Sorin Shtirbu (shtirbu@fnal.fnal.gov) is as
  985.    follows:
  986.    select 33 - datepart(day,
  987.         dateadd(day,32,
  988.              dateadd(day,
  989.                   0-datepart(day,getdate())+1,getdate()) ))
  990.    
  991.    ++++++++++++++++++++++++++++++++++++++++++++++
  992.    Q12. How can I recursively retrieve the rows in a bill of
  993.       materials type problem?
  994.  
  995.    Answer:    Rob Hawkes provided this interpretation of an idea from "A Guide
  996.    To Sybase and SQL Server" by McGoveran and Date and solved the problem with a
  997.    stored procedure.
  998.    
  999.    create proc getMenuLeaves (@current int) as
  1000.    
  1001.    /* Given a menu_id in the hierarchy defined by the menu_link table, this
  1002.    ** procedure returns all nodes (menu_ids) which are descendants of the given
  1003.    ** node and which are leaf nodes (no descendants). */
  1004.    
  1005.        set nocount on
  1006.        declare @root int
  1007.        declare @level int
  1008.        select @root = @current
  1009.        create table #stack (item int, level int)
  1010.        create table #leaves (leaf int)
  1011.        insert into #stack values (@current, 1)
  1012.        select @level = 1
  1013.        while @level > 0
  1014.        begin
  1015.            if exists(select * from #stack where level = @level)
  1016.            begin
  1017.                select @current = item from #stack where level = @level
  1018.                if not exists (select menu_id_child from eeddb..menu_link
  1019.                        where menu_id_parent = @current)
  1020.                begin
  1021.                   insert #leaves values (@current)
  1022.                end
  1023.    
  1024.                delete from #stack
  1025.                   where level = @level and item = @current
  1026.    
  1027.               insert #stack select menu_id_child, @level+1
  1028.                   from eeddb..menu_link where menu_id_parent = @current
  1029.    
  1030.               if @@rowcount > 0 select @level = @level+1
  1031.            end
  1032.            else select @level = @level-1
  1033.        end
  1034.        select * from #leaves where leaf != @root order by leaf
  1035.    return
  1036.    
  1037.    ++++++++++++++++++++++++++++++++++++++++++++++
  1038.    Q13. What mechanism does Sybase offer to control concurrency
  1039.       when multiple users are doing *select - think - update* kind of
  1040.       operations?
  1041.  
  1042.    Answer:    Sybase offers "browse mode" for such applications.
  1043.    Conceptually, browse mode involves three steps:
  1044.  
  1045.    1.   Select result rows containing columns derived from one or more database
  1046.    tables.  The user now looks at returned data and decides which rows to update
  1047.    - this is the thinking part.
  1048.  
  1049.    2.   Where appropriate, change values in columns of the result rows (not the
  1050.    actual database rows, but copies stored in program variables by step (1), one
  1051.    row at a time.
  1052.  
  1053.    3.   Update the original database tables, one row at a time, using the new
  1054.    values in the results rows.
  1055.  
  1056.    To implement this scheme the application needs to use the SELECT with "FOR
  1057.    BROWSE" option when reading the rows, copy the column values into program
  1058.    variables, one row at a time, change the variables values when and where
  1059.    equired (usually in response to user input) and finally, execute an UPDATE
  1060.    command that updates the database row corresponding to the current result row
  1061.    using the "timestamp" column for the table (Every table updated in this
  1062.    manner must have the 'timestamp' column in the table).
  1063.  
  1064.    At step (3) the where clause refers to the value of the row's timestamp
  1065.    column stored when it was returned in step 1.  If someone else has updated
  1066.    the row in the meantime, its timestamp value will have change and the update
  1067.    will fail, thus telling the application that the row has been modified by
  1068.    another user.  When this happens, the application can decide to either forget
  1069.    the update for that row or re-read and show the user then new values for that
  1070.    row and decide if s/he wants to proceed with the update, do a modified
  1071.    version of the update, or whatever.
  1072.  
  1073.    Browse mode is documented in the Sybase Open Client DB-Library reference
  1074.    manuals and the T-SQL Commands Reference Manual 4.9.1.  Although historically
  1075.    only used from 3GL programming languages like c, browse mode is implemented
  1076.    to varying degrees by some 4GL tools such as Powerbuilder, etc (but not APT) 
  1077.    and can in fact be used from T-SQL itself (thus allowing application like
  1078.    APT access to it.)
  1079.  
  1080.    Care must be taken when using browse mode on PC based clients.  Not all 4GLs
  1081.    represent date and time datatypes at the same precision as expected by
  1082.    Sybase.  This can result in an application where an update never, OK almost
  1083.    never, takes place.  In situations like this, another user column can be
  1084.    added and treated much the same way as the timestamp column works, i.e., only
  1085.    update when the column has the same value as it did when you selected it out
  1086.    of the database.  Not quite as elegant since you have to update this column
  1087.    yourself.
  1088.  
  1089.    It is expected that the functionality offered by cursors, implemented in the
  1090.    upcoming System 10 SQL Server and Open Client, will substantially overlap and
  1091.    exceed the functionality provided by browse mode.
  1092.    
  1093.    ++++++++++++++++++++++++++++++++++++++++++++++
  1094.    Q14.  In what order are defaults, rules, triggers, etc. enforced/executed?
  1095.  
  1096.    Answer:    Execution occurs in the following order:.
  1097.  
  1098.    1. Default substitution occurs.  Substitute a default value for each column
  1099.       that does not have a user supplied value (if a default value exists).  If
  1100.       a column has two defaults, one bound directly to the column, and one
  1101.       bound to the type on which the column is defined, the default bound
  1102.       directly to the column takes precedence.  Note that if the user supplies
  1103.       any value whatsoever for a column, including NULL, the default
  1104.       substitution will not occur.
  1105.  
  1106.    2. The transaction will be automatically rolled back if, after default
  1107.       substitution, any columns forbidding nulls now contain a null value.
  1108.  
  1109.    3. Rule enforcement occurs.  Determine if any column violates a rule
  1110.       associated with that column either directly or through the columns type.
  1111.       If a column has two rules, one bound directly to the column, and one
  1112.       bound to the type on which the column is defined, the rule bound directly
  1113.       to the column takes precedence.
  1114.  
  1115.    4. The transaction will be automatically rolled back if any column violates
  1116.       the associated rule, including columns in which default values were
  1117.       substituted.
  1118.  
  1119.    5. Roll back any transaction that contains rows which would violate a unique
  1120.       index on the table.
  1121.  
  1122.    6. Execute the trigger to enforce user defined integrity.
  1123.    
  1124.  
  1125. ----------------------------------------------------------------------
  1126. 2.4.     Sybase Bulk Copy
  1127.    
  1128.    
  1129.    ++++++++++++++++++++++++++++++++++++++++++++++
  1130.    Q1.  When using Bulk Copy (BCP) to copy a database, is the copy
  1131.       equivalent to the original in terms of performance?
  1132.  
  1133.    Answer:    Copying via bcp will remove the "holes" and usually compact the
  1134.    rows more contiguously than the original.  If your table is large, and has
  1135.    had many rows deleted throughout the table, performing this table rebuild may
  1136.    improve I/O performance.
  1137.  
  1138.    Meaningful "holes" only exist when larger tables with a clustered index have
  1139.    a small fillfactor, and/or have small groups of rows deleted from areas
  1140.    spanning most of the table.  These gaps are not large on a per-page basis,
  1141.    since through all manipulations, pages are always kept at least half-full,
  1142.    and rows on a page are always congituous (free space on any page is kept
  1143.    together at the  end of the page).
  1144.  
  1145.    Recreating the clustered index will fill these on-page gaps, placing a
  1146.    uniform number of rows on all pages.  The clustered index should be recreated
  1147.    using the following methods.
  1148.    
  1149.         SELECT INTO another_table,
  1150.         TRUNCATE TABLE original_table,
  1151.         INSERT original_table SELECT * from another_table
  1152.         
  1153.         OR
  1154.         
  1155.         bcp out,
  1156.         TRUNCATE TABLE original_table,
  1157.         bcp in
  1158.    
  1159.    Related to this topic is the notion of external fragmentation of a table's
  1160.    allocated extents (chains of 8 pages, or table "building blocks").  While not
  1161.    impacting table I/O effectiveness, this type of fragmentation is a greater
  1162.    contributor than the above internal fragmentation to excessive reserved space
  1163.    allocation on a table, space not yet re-used after being partially
  1164.    deallocated in a DELETE.
  1165.  
  1166.    Fragmented extents occur only when less than one extent (8 - 2K pages) of
  1167.    contiguous rows are ever deleted.  Until completely emptied, extents remain
  1168.    allocated to the table indefinetly, effectively reserving small groupings of
  1169.    empty pages which could otherwise be freed for use by other tables in the
  1170.    database.  This type of fragmentation may be removed in exactly the same
  1171.    manner as described above.
  1172.  
  1173.    The only performance gains to be had from rebuilding are realized via
  1174.    increased row-per-page counts for I/O done to retrieve any page with a
  1175.    desired row on it.  (You get more info if you get 16 rows for reading 8 pages
  1176.    at 2 rows per page than you would if you had only 1 row per page, and only
  1177.    got 4 rows for the same 8 pages read).
  1178.    When row size is large, there is often so little free space left by deleting
  1179.    large rows that SQL Server's page splitting and filling algorithms have
  1180.    already optimally filled all gaps on the ends of pages.
  1181.    The bottom line is, like most choices in physical database design, there are
  1182.    always tadeoffs.  You must always apply the exact requirements of your
  1183.    application.
  1184.  
  1185.    BCP-ing into an empty table with indexes, or building the indexes after the
  1186.    data is all in WILL indeed fill in the gaps in the extent chains where rows
  1187.    had been deleted in the original source table. Rows are always compacted to
  1188.    have no spaces between rows.
  1189.    Unless you note a substantial difference between the reserved space and the
  1190.    allocated space given by sp_spaceused for both tables, the performance
  1191.    difference is typically not that great.
  1192.    The best way to copy a database is to use DUMP DATABASE and LOAD DATABASE...
  1193.    it's just one operation, and produces an exact page-by-page copy of the
  1194.    original database, "spaces" and all.
  1195.  
  1196.    Thanks to Benjamin von Ullrich
  1197.    
  1198.    ++++++++++++++++++++++++++++++++++++++++++++++
  1199.    Q2.  Can BCP load null dates?
  1200.  
  1201.    Answer:    BCP can load null dates if there is nothing between the delimiters
  1202.    for the columns. If it encounters a space it converts that to Jan 1, 1900.
  1203.    Here is an example:
  1204.  
  1205.         create table foo
  1206.          (seq_no int not null,
  1207.          date1 datetime null,
  1208.          date2 datetime null)
  1209.  
  1210.    The following is the contents of a file that we are going to bcp into table
  1211.    foo. I am using a tilde to delimit columns and a tilde followed by a return
  1212.    (\n) as a row terminator.
  1213.  
  1214.    1~ ~~
  1215.    2~~ ~
  1216.    3~~~
  1217.  
  1218.    Now we use bcp with the delimiters specified above.
  1219.  
  1220.    bcp foo in foo.dat -c -t~ -r"~\n"
  1221.  
  1222.    Starting copy...
  1223.    3 rows copied.
  1224.    Clock Time (ms.): total = 37 Avg = 12 (81.08 rows per sec.)
  1225.    Via isql let's look at the results.
  1226.    1> select * from foo
  1227.    2> go
  1228.     seq_no date1 date2
  1229.     ----------- ------ ------
  1230.     1 Jan 1 1900 12:00AM NULL
  1231.     2 NULL Jan 1 1900 12:00AM
  1232.     3 NULL NULL
  1233.    
  1234.    (3 rows affected)
  1235.    
  1236.  
  1237. ----------------------------------------------------------------------
  1238. 2.5.     Sybase Backup and Recovery
  1239.    
  1240.    
  1241.    ++++++++++++++++++++++++++++++++++++++++++++++
  1242.    Q1.  How can I dump more than one database to a single tape?
  1243.  
  1244.    Answer:    Tell Sybase that the tape device is really a disk. Declare the
  1245.    tape /dev/nrst? as a "disk" device (sp_addumpdevice "disk", ...). Then
  1246.    successive dumps will follow each other on tape. Of course, you've got to
  1247.    maintain your own directory of what's on the tape. Use  "mt -f /dev/nrst0
  1248.    sta"  to check.  This method is not supported by Sybase.
  1249.  
  1250.    Another alternative is to write your databases dumps to files and write the
  1251.    files to tape using standard unix commands.  Multiple dumps can safely be put
  1252.    onto a tape using this method, but you must maintain your own index.
  1253.    The first of the two methods is commonly practiced, but not supported by
  1254.    Sybase.  One article originating from Sybase stated...
  1255.  
  1256.    Please save yourself a lot of grief and don't do this (First Method above).
  1257.    The various platforms handle tapes in slightly different ways and the various
  1258.    Sybase server ports make slightly different attempts to work around this. On
  1259.    some platforms the above suggestion will work, but on some other platforms,
  1260.    you overwrite your dump, and on yet others, it just fails. Worse yet, from OS
  1261.    release to OS release, and Sybase release to Sybase release, the behavior of
  1262.    any specific platform can change.
  1263.  
  1264.    The point of doing dumps is that you know your data is safe. If you are doing
  1265.    something that is "not really supported", then how do you know your data is
  1266.    safe? If you don't care if your data is safe, save even more tapes and don't
  1267.    do dumps at all.
  1268.  
  1269.    None of the above is meant to imply that the Sybase dump mechanism is better
  1270.    or worse than any other possibility. However, it is the mechanism Sybase
  1271.    provides and supports.
  1272.  
  1273.    Thanks to David Gould
  1274.  
  1275.    And one final word, Sybase System 10 includes a Backup Server, which will
  1276.    handle this problem.  DataTools, Inc. also provides a product that can backup
  1277.    multiple Sybase databases on a single tape.  See section 9 of this document.
  1278.    
  1279.  
  1280. ----------------------------------------------------------------------
  1281. 2.6.     Upgrading the Sybase Server
  1282.    
  1283.    
  1284.    ++++++++++++++++++++++++++++++++++++++++++++++
  1285.    Q1.  I'm upgrading the Server from version <x> and/or operating
  1286.       system <p> to version <y> and/or operating system <q>. Any advice?
  1287.  
  1288.    Answer:    In general,  read the install guide and release bulletin for the
  1289.    latest news on the recommended OS levels for upgrades.  (read these ALL THE
  1290.    WAY THROUGH BEFORE YOU START, not as you go!)
  1291.  
  1292.    If your planned OS level is not mentioned, call Sybase Technical Support and
  1293.    find out if your *current* SQL Server is certified on the new SQL Server's
  1294.    certified operating system.  Most SQL Server upgrades require that you be
  1295.    able to run both SQL Server versions on the same machine.  Also, if the
  1296.    upgrade fails for some reason, you may need to fall back to your previous
  1297.    version of SQL Server.  This fallback should always be on a certified OS
  1298.    version.
  1299.  
  1300.    Above all, make a DUMP DATABASE backup of ALL databases, and ALWAYS use
  1301.    'sybconfig' to do the upgrade.  Doing an upgrade by hand can destroy your SQL
  1302.    Server.  If you have the time, computing power, and disk space, consider
  1303.    building a new SQL Server from the backups you make of your production
  1304.    server, and trying a trial upgrade on this "test" server.  Don't run the test
  1305.    server for long, as you license agreement doesn't allow indefinite use of
  1306.    multiple copies of your software.
  1307.    
  1308. ----------------------------------------------------------------------
  1309. 2.7.     Sybase Security
  1310.    
  1311.    
  1312.    ++++++++++++++++++++++++++++++++++++++++++++++
  1313.    Q1.  What different mechanisms are there to control Sybase security?
  1314.  
  1315.    Answer:    The following summarizes techniques to control security with SQL
  1316.    Server that I have received from various sources plus some comments of my
  1317.    own. My concern was how to control updates to a database in an environment
  1318.    with end-user "query"" tools that include update capabilities (e.g. Pioneer,
  1319.    Q+E, Microsoft Access). I want to especially thank those who responded to my
  1320.    question. All responses where useful.
  1321.  
  1322.    There are four fundamental methods, each described in more detail below: (1)
  1323.    adopted authority; (2) login ID; (3)gatekeeper; (4) triggers. All techniques
  1324.    are premised on fundamental security features of user authentication and
  1325.    grant/revoke permissions to resources. Each technique has a cost and must be
  1326.    weighed against the risk/benefit.
  1327.  
  1328.    Where available, references are cited. Particularly useful for those with
  1329.    access to CompuServe are Microsoft's Knowledge Base (MSKB) and Microsoft's
  1330.    Software Library (MSL).
  1331.  
  1332.    1. Adopted authority.
  1333.  
  1334.    This seems to be the most common approach making use of SQL Servers authority
  1335.    checking structure -- if the owner of an object (stored procedure or view)
  1336.    has necessary authority to all underlying objects, then authorized users of
  1337.    this object have the same authority. All updates are done via stored
  1338.    procedures owned by a user with update authority to underlying objects. Users
  1339.    are granted authority to stored procedures but do not have update authority
  1340.    to any tables.   This approach encapsulates your database as much as possible
  1341.    using views and stored procedures."
  1342.  
  1343.    While one can often choose between use of views and stored procedures for
  1344.    SELECT access to data, it is important to note the following traits of these
  1345.    two object types:
  1346.  
  1347.       Views are best used for data access whose access methods must be
  1348.       arbitrary.  If you need to run a query, to join to other tables for
  1349.       example, a view does the best job.
  1350.  
  1351.       Stored procedures may be parameterized, but the data returned cannot be
  1352.       expanded or limited in any way (short of rewriting the procedure).  Joins
  1353.       of tables, and especially other views can be messy from an optimization
  1354.       standpoint, so keeping complete control through stored procedures can be
  1355.       attractive.
  1356.  
  1357.    Sybase T-SQL allows updates through views, but only under certain conditions.
  1358.    Stored procedures are best used for all write operations, since they suffer
  1359.    from no restrictions for updates, but can be set up to update anything that
  1360.    is needed, such as several tables opposed to the UPDATE command's
  1361.    restricstions of only one table per command.
  1362.  
  1363.    Note that the object ownership chain is broken between databases!  Since a
  1364.    server login may have completely different privileges from one database to
  1365.    another, the access manager checks the runtime user's permissions against
  1366.    those of any object residing outside the current database.
  1367.  
  1368.    The assumption here is that users are not aware of stored procedures since
  1369.    they will only be used by application programs for database maintenance. It
  1370.    is possible to "hide" the stored procedures; possibly in a totally different
  1371.    database. Still the knowledgeable user could find them and execute them.
  1372.    Programmers might object to the use of stored procedures versus direct use of
  1373.    SQL.
  1374.  
  1375.    As long as you REVOKE all permissions which exist on database objects (in
  1376.    lieu of the stored procedures's ownership-inheritance permissions), there is
  1377.    no way the application tables may be accessed in any way outside of the
  1378.    application stored procedures.  Running procedures outside of any application
  1379.    should not result in any adverse situation with your database, as long as
  1380.    your application is "well-written" (i.e., doesn't flip out if you run one SP
  1381.    without running some other one right after it), and uses triggers or other
  1382.    stored procedures to maintain referential integrity.
  1383.  
  1384.    In the case where applications are written using end-user tools such as Q+E
  1385.    and Excel, Robert Thomas describes hiding the calls to stored procedures
  1386.    using DDE or DLL calls; possibly using a special password as a parameter to
  1387.    the stored procedure. He also recommends making sure sp_helptext for these
  1388.    procedures return nothing. He sometimes uses a technique of mixing DDE and
  1389.    DLL calls in which in the middle of a DDE conversation he establishes a
  1390.    temporary second login to SQL Server for update purposes using DLL calls.
  1391.    See MSKB article Q47270: "INF: SQL Access Permissions and Trigger Execution"
  1392.    which describes SQL Server adopted authority structure using triggers.
  1393.    However, this concept applies as well to stored procedures and views.
  1394.  
  1395.    2. Login IDs
  1396.  
  1397.    The basic idea is to use different login IDs for update and query use. The
  1398.    trick is to keep the one for update hidden and unobtrusive. There are several
  1399.    techniques for doing this with varying degrees of sophistication.
  1400.  
  1401.    Maintenance applications could use a single special ID and password that
  1402.    allows update privileges; while normal user IDs have read only authority.
  1403.    This is based on the assumption that access to applications is controlled and
  1404.    that steps are taken to make sure the special login does not become common
  1405.    knowledge. One problem is that it is difficult to tell who is logged onto the
  1406.    database since they all use the same ID.
  1407.  
  1408.    Lawrence Bertolini wrote with a table driven variation of the above. A
  1409.    special login is used by an application to access, of course, a special
  1410.    table. This table cross references a normal login ID to a special login ID.
  1411.    Once the special ID is located, the application logoffs and then back on
  1412.    using the special ID. For example, my normal ID might be "seth" but my
  1413.    special ID might be"seth_12x9t". Again, normal precautions must be taken to
  1414.    ensure that this scheme is not compromised.
  1415.  
  1416.    3. Gatekeeper
  1417.  
  1418.    The most sophisticated approach is to control all logins with a custom
  1419.    written front-end gatekeeper to SQL Server. All requests to SQL Server must
  1420.    pass through this program which can determine the privileges needed by the
  1421.    requester. The action taken by the program is flexible. Two possibilities are
  1422.    to use the two login ID approach as above or to analyze each request
  1423.    rejecting those that are not acceptable (e.g. update from Q+E). This approach
  1424.    also allows maintaining an audit trail of SQL Server logins and requests. The
  1425.    key issue is authenticating the requesting program. The login ID can be
  1426.    authenticated using the native operating system security.
  1427.  
  1428.    This technique is described in Microsoft's "Open Data Services User's Guide"
  1429.    as the SECURE application. Manual and source are included with SQL Server
  1430.    4.2. It is also described in MSKB article Q79958: "INF: ODS Security and
  1431.    Auditing Application". Source for SECURE42 should be in MSL as "S13264"
  1432.    however it is missing as of this writing but I am told it will be added
  1433.    within a week or two. This program requires Microsoft's SQL Server
  1434.    Programmer's Reference for C.
  1435.  
  1436.    For those of you not using the Microsoft SQL Server, Sybase's Open Server
  1437.    product was designed exactly for this type of application:  when you need an
  1438.    arbitrary software agent to look just like a SQL Server to Sybase compatible
  1439.    tools.  Open Server allows you to construct your own "SQL Server", from top
  1440.    to bottom, with the SQL Server networking and API to do all the
  1441.    communications with clients, making your program look like a SQL Server, but
  1442.    actually do just about anything you can program in supported 3GL's.
  1443.  
  1444.    4. Triggers
  1445.  
  1446.    This technique places update control logic inside triggers associated with
  1447.    each table.  For example, the trigger could check a table to make sure the
  1448.    requesting application was authorized for updates.  This technique is
  1449.    described in MSKB article Q66678: "INF: Providing Application Security
  1450.    Through Triggers in SQL". Obviously a trigger needs to be written for each
  1451.    table however the update check could be placed in its own stored procedure
  1452.    and work for all tables.
  1453.  
  1454.    5.   Other ideas
  1455.  
  1456.    Possibly an obvious Answer: don't provide tools for ad hoc queries that
  1457.    include update capabilities. It seems in the personal computer arena this is
  1458.    unrealistic.
  1459.  
  1460.    Another option is physically separate database for update and ad hoc query.
  1461.    There is a fair amount of overhead but actually might work well where
  1462.    performance is critical for maintenance transactions.
  1463.  
  1464.    Disclaimer:  I have tried to present the above information as accurately as
  1465.    possible including citations. However, I leave it up to you to verify the
  1466.    information and determine its correctness and applicability to your needs.
  1467.  
  1468.    Provided by: Seth Siegal with additions by Benjamin von Ullrich
  1469.    
  1470.  
  1471. ----------------------------------------------------------------------
  1472. 2.8.     Sybase Database Administration
  1473.    
  1474.    
  1475.    ++++++++++++++++++++++++++++++++++++++++++++++
  1476.    Q1.  Why does the transaction log on the model database keep filling up?
  1477.  
  1478.    Answer:    Up to release 4.8, SQL server stored tempdb's next object_id in
  1479.    the log of the model database.I don't remember exactly why this was
  1480.    necessary, but i think it has something to do with avoiding re-issuance of
  1481.    object_ids that may be in stored procedures and/or transaction logs of all
  1482.    server databases. Since model is copied into tempdb at boot time, it seemed
  1483.    logical to store the next object id in model. All that was logged was a 4-
  1484.    byte integer, so it could take months for the log in model to fill up. This
  1485.    problem was fixed in version 4.8 . The next object id is now stored
  1486.    elsewhere.
  1487.    
  1488.    
  1489.    ++++++++++++++++++++++++++++++++++++++++++++++
  1490.    Q2.  Why does my transaction log fill up even when I have
  1491.       allocated lots of space for it?
  1492.  
  1493.    Answer:    The capacity of the log is limited by two things:
  1494.  
  1495.    1.   The total allocated size of the log
  1496.    2.   The frequency of its truncation (or DUMP).
  1497.  
  1498.    You can have a very active system with small transactions, and not fill up
  1499.    the log if all transactions commit very quickly (optimal behaviour for SQL
  1500.    Server) and you dump the log very often.  You can also have an ad-hoc system,
  1501.    in which transaction size and duration may vary.  In this case, the following
  1502.    paragraphs apply.
  1503.  
  1504.    Due to the sequential nature of the log, only the inactive portion of the log
  1505.    may be truncated by any DUMP TRANSACTION command. The inactive portion of the
  1506.    log runs from the "beginning" to the page which has the BEGIN XACT record for
  1507.    the oldest *active* (uncommitted) transaction. Pages which follow this oldest
  1508.    active transaction in the log are considered active for the purposes of DUMP
  1509.    TRANSACTION, since they may depend on changes made (yet to be committed or
  1510.    still to be rolled back) by this transaction. Recovery (at LOAD TRAN or
  1511.    system startup time) replays transactions as committed or rolled back in the
  1512.    exact order in which they appear in the log, so portions appearing in the log
  1513.    after an uncommitted transaction may not be removed.
  1514.    The implication here is that given a large enough or long-running enough
  1515.    transaction, one can hold up the entire log (from dumping, not from continued
  1516.    logging!) while the transaction is still pending. If your log fills up, and
  1517.    you have a very old transaction that started at the beginning of the log, no
  1518.    DUMP TRAN command can or will clear it until the transaction COMMITs or is
  1519.    ROLLed BACK.
  1520.  
  1521.    The only things you can do in this case are:
  1522.  
  1523.    1.  ALTER DATABASE to add more space to the log, hopefully allowing enough
  1524.       space & time for your old transaction(s) to commit (find that user who
  1525.       typed BEGIN TRAN ... UPDATE/INSERT/DELETE ... and the went to lunch!)
  1526.       This only makes sense if you know the transaction must finish. KILL the
  1527.       long-running process/transaction.
  1528.  
  1529.    2. Shut down the sql server to terminate the long-running/old transaction.
  1530.  
  1531.    These last two effectively terminate the transaction without a COMMIT, making
  1532.    it get rolled back upon recovery. This is a fairly drastic action to kill a
  1533.    process to clear a log.... if you can kill the client process, or type ^C to
  1534.    abort from the same, please do so to achieve a cleaner and easier return to
  1535.    normal processing.
  1536.  
  1537.    Long-term, it is best to avoid long/log-intensive transactions.  This may be
  1538.    done by breaking up large deletes into smaller pieces by adding a WHERE
  1539.    clause to target a range of rows.  You can also use a WHILE loop, re-
  1540.    selecting the MIN() or MAX() of an int or char key into a variable whose
  1541.    value you check for NOT NULL, and then use to alter the table.  This advice
  1542.    applies the same to DELETEs, UPDATEs, and similarly for INSERTs.
  1543.    If your problem transaction is to delete all rows in a table, consider using
  1544.    the TRUNCATE TABLE command. This command uses a minuscule proportion of log
  1545.    versus a DELETE of all rows, as it merely logs the deallocation of pages
  1546.    assigned tothe table, instead of an image of every row deleted. For this
  1547.    reason, it is also MUCH faster than DELETE for most good-sized tables.
  1548.    Permission to use TRUNCATE TABLE is only available to the dbo, however.
  1549.    Benjamin von Ullrich
  1550.    
  1551.    
  1552.    ++++++++++++++++++++++++++++++++++++++++++++++
  1553.    Q3.  Is there a way to turn off logging altogether? How about putting 
  1554.       the transaction logs on `/dev/null'? How does tempdb avoid logging?
  1555.  
  1556.    Answer:    The transaction logs are an integral part of Sybase operations. It
  1557.    must be able to read from as well as write to the log device. This is why
  1558.    /dev/null won't work.
  1559.  
  1560.    What you can do is use "sp_dboption dbname, trunc, true".  This will
  1561.    automatically clear out the INACTIVE PORTION of transaction log every minute
  1562.    or so (when the CHECKPOINT SLEEP process does its work).  This is the way
  1563.    tempdb works.  Keep in mind that you have just prevented recovery from
  1564.    incremental transaction log dumps (dump tran) and that you can ONLY recover
  1565.    the database from the last full database backup (dump database).
  1566.    
  1567.    
  1568.    ++++++++++++++++++++++++++++++++++++++++++++++
  1569.    Q4.  Is there any reason not to have `truncate log on checkpoint' turned 
  1570.       on for the model database?
  1571.  
  1572.    Answer:    Since this database is the template for all databases at CREATE
  1573.    DATABASE time, setting this option on in model makes it be automatically set
  1574.    on for all new databases as they are created. Aside fro the simple fact that
  1575.    this may not be what you want on all new databases, if you are in the midst
  1576.    of a frenzied recovery of a major production database (say, in the middle of
  1577.    the day, while all your users are down), and you load your database backup,
  1578.    the first gift your clever option on model will give you is a truncated log
  1579.    in front of all of the transaction log dumps you were about to apply to bring
  1580.    the database you just loaded up to the time of failure. Truncating the log at
  1581.    any time between LOAD DATABASE and your last LOAD TRANSACTION blasts a hole
  1582.    in the log chain and halts the recovery operation then and there.
  1583.    
  1584.    
  1585.    ++++++++++++++++++++++++++++++++++++++++++++++
  1586.    Q5.  Why doesn't the Sybase kill command work?
  1587.  
  1588.    Answer:    Killing a Sybase process will result in one of four reactions:
  1589.  
  1590.    1.  The process is an ordinary retrieve transaction, i.e. SELECT, and it
  1591.       dies immediately.  (Actually it dies as soon as the process wakes up
  1592.       (when an I/O completes), and the engine becomes available to run a task,
  1593.       or a necessary lock is acquired).
  1594.  
  1595.    2. The process is an update transaction. It does not die until the server
  1596.       has rolled back the transaction. The time is directly related to the size
  1597.       of the transaction.
  1598.  
  1599.    3. The process is a DBCC transaction. Sybase forks a separate process for
  1600.       the transaction, and the new one is out of the users' control. DBCC
  1601.       checks tables index by index and can only be killed when it finishes one
  1602.       index and is ready for the next one. It may take anywhere from several
  1603.       minutes to four hours to die.  Note:  DBCC elapsed time to complete any
  1604.       check is directly related to the size of the object(s) being checked.
  1605.       There is no upper elapsed time limit.  The good news is that System 10
  1606.       has many new, documented checktable() and checkalloc() "subset" commands
  1607.       which allow the DBA choices in the level of checking to do versus the
  1608.       time available versus data integrity requirements.
  1609.  
  1610.    4. The process is sleeping. We cannot kill a sleeping process. When an end-
  1611.       user process gets disconnected, we cannot kill the Sybase process and
  1612.       release the locks.  This can happen if a PC-client is rebooted or turned
  1613.       off with an active connection.
  1614.  
  1615.    System 10 will provide an unconditional kill.
  1616.    
  1617.    
  1618.    ++++++++++++++++++++++++++++++++++++++++++++++
  1619.    Q6.  What are some of the undocumented features of DBCC?
  1620.  
  1621.    Answer:    There are a number of undocumented DBCC options that tech support
  1622.    uses to analyze your database. Some of these are DESTRUCTIVE and tech support
  1623.    will not help you if you screw up your database using one of these commands.
  1624.    They can also tell what you have done.
  1625.  
  1626.    There are NO SECRETS in the undocumented dbcc commands; they are a fleeting
  1627.    sert of diagnostic and repair utilities to help fix extreme problems with
  1628.    database pages, index structures, ans sticky problems with system tables.
  1629.    They are best only used by Sybase Technical Support, since their structure
  1630.    and applicability towards any given problem is always best judged from those
  1631.    who are extremely familiar and experienced with a great variety of failures
  1632.    and associated damage, and know when to use and not to use each dbcc command.
  1633.    Sybase generally only uses them when backups are not available or the backup
  1634.    recovery options are not optimal with regard to the application's
  1635.    availability requirements.  The bottom line is:  knowing all dbcc commands is
  1636.    no panacea, and can EASILY get you into more trouble than you are already in
  1637.    when you need such tools.
  1638.  
  1639.    The System 10 SysAdmin Guide includes a NEW, LARGE section devoted
  1640.    exclusively to dbcc, including hit\nts on usage, planning a dbcc strategy to
  1641.    fit in with your backup and recovery plans, and performance impact analysis
  1642.    data to help you make an informed desision on database maintenance.
  1643.    
  1644.    
  1645.    ++++++++++++++++++++++++++++++++++++++++++++++
  1646.    Q7.  Why don't the dbcc commands produce any output on my screen?
  1647.  
  1648.    Answer:    Most of the dbcc commands direct their output to the console (the
  1649.    terminal on which the Sybase dataserver was started).  No output is seen on
  1650.    the terminal when executing a dbcc command at any terminal other than the
  1651.    console.  There are several exceptions, but I can't remember which commands
  1652.    automatically send output to the local terminal right now.
  1653.  
  1654.    To redirect dbcc output to your terminal rather than the console, type from
  1655.    the command line:
  1656.  
  1657.         dbcc traceon(3604)
  1658.         go
  1659.  
  1660.    Subsequent dbcc output will appear at the local terminal.  Output is also
  1661.    logged into the errorlog file.
  1662.    
  1663.    
  1664.    ++++++++++++++++++++++++++++++++++++++++++++++
  1665.    Q8.  What are the trace flags used for and what are some of the more
  1666.       common flags?
  1667.  
  1668.    Answer:    Trace flags disable or enable certain features with the database
  1669.    server.  They may be executed from the command line through the dbcc command
  1670.    or may be installed in the RUNSERVER file when prefixed by a '-T'.  There are
  1671.    a number of trace flags that can be used.  An initial list follows:
  1672.    
  1673.         dbcc traceon(3604)  redirects dbcc output to your screen rather than the
  1674.         console.
  1675.         
  1676.         dbcc traceon(3605)  redirects dbcc output to the errorlog.
  1677.    
  1678.    
  1679.    ++++++++++++++++++++++++++++++++++++++++++++++
  1680.    Q9.  Is there a way to accurately estimate how much space a table and its
  1681.       indexes are going to take?
  1682.  
  1683.    Answer:    FYI, lot's of people have asked for it, and here it is! the
  1684.    officially UNSUPPORTED stored procedure sp_estspace. It works under 4.9.2,
  1685.    but I make no guarantees. What's it good for: estimating the size of tables
  1686.    and their indexes given an existing table and index schema.
  1687.    Have fun.
  1688.  
  1689.    **************************************************
  1690.    Doug Smith Sr. Instructor
  1691.    Sybase Professional Services, Northwest District
  1692.    ***************************************************
  1693.    create procedure sp_estspace
  1694.    /*   A procedure to estimate the disk space requirements of a table
  1695.    **   and its associated indexes.
  1696.    **   November 21, 1991
  1697.    **   Written by Malcolm Colton with assistance from Hal Spitz
  1698.    **   Modified by Jim Panttaja November 25, 1991
  1699.    */
  1700.         (@table_name   varchar(30)=null, /* name of table to estimate */
  1701.          @no_of_rows   float = 1,      /* number of rows in the table */
  1702.          @fill_factor  float = 0,     /* the fill factor */
  1703.          @cols_to_max  varchar(255) =null /* variable length columns for which
  1704.                             to use the maximum rather than 50% of
  1705.                             the maximum length  */
  1706.          )
  1707.    as
  1708.    
  1709.    declare @msg   varchar(120)
  1710.    
  1711.    /*   Give usage statement if @table_name is null */
  1712.    
  1713.    if @table_name = null or @no_of_rows = 1
  1714.    begin
  1715.         print `Usage is:'
  1716.         print ` estspace table_name, no_of_rows, fill_factor, cols_to_max'
  1717.         print `where table_name is the name of the table,'
  1718.         print ` no_of_rows is the number of rows in the table,'
  1719.         print ` fill_factor is the index fill factor (default = 0) `
  1720.         print ` cols_to_max is a list of the variable length columns for which'
  1721.         print ` to use the maximum length instead of the average'
  1722.         print `              (default = null)'
  1723.         print `Examples: estspace titles, 10000, 50, "title, notes"'
  1724.         print ` estspace titles, 50000'
  1725.         print ` estspace titles, 50000, 0, null, 40'
  1726.         return
  1727.    end
  1728.    
  1729.    declare   @sum_fixed     int,
  1730.         @sum_var  int,
  1731.         @sum_avgvar    int,
  1732.         @table_id int,
  1733.         @num_var  int,
  1734.         @data_pages    float,
  1735.         @sysstat  tinyint,
  1736.         @temp          float,
  1737.         @index_id int,
  1738.         @last_id  int,
  1739.         @i        int,
  1740.         @level_pages   float,
  1741.         @key      varchar(30),
  1742.         @usertype tinyint,
  1743.         @type          tinyint,
  1744.         @level         tinyint,
  1745.         @vartype  smallint,
  1746.         @more          bit,
  1747.         @next_level    float,
  1748.         @rows_per_page smallint,
  1749.         @row_len  smallint,
  1750.         @length        tinyint,
  1751.         @index_name    varchar(30),
  1752.         @page_size     smallint,
  1753.         @page_K        tinyint,
  1754.         @index_type    varchar(20),
  1755.         @factor        float
  1756.    
  1757.    select    @sum_fixed=0,
  1758.         @sum_var=0,
  1759.         @sum_avgvar=0,
  1760.         @table_id=0,
  1761.         @num_var=0,
  1762.         @data_pages=0,
  1763.         @row_len=0,
  1764.         @sysstat=0
  1765.    
  1766.    set nocount on
  1767.    
  1768.    /* Make sure table exists */
  1769.    
  1770.    select @sysstat = sysstat,
  1771.         @table_id = id
  1772.              from sysobjects where name = @table_name
  1773.              and uid = user_id()
  1774.    
  1775.    if @sysstat & 7 not in (1,3)
  1776.    begin
  1777.         select @msg = "I can't find the table "+@table_name
  1778.         print @msg
  1779.         return
  1780.    end
  1781.    
  1782.    /* Get machine page size */
  1783.    
  1784.    select    @page_size = low - 32
  1785.         from master.dbo.spt_values
  1786.              where type = `E'
  1787.              and number = 1
  1788.    
  1789.    select @page_K = (@page_size +32) /1024
  1790.    
  1791.    if @fill_factor !=0
  1792.         select @fill_factor = @fill_factor / 100.0
  1793.    
  1794.    /* Create tables for results */
  1795.    
  1796.    create table #results
  1797.         (name     varchar(30),
  1798.          type     varchar(12),
  1799.          level    tinyint,
  1800.          pages    float,
  1801.          Kbytes float)
  1802.    
  1803.    create table #times
  1804.         (name          varchar(30),
  1805.          type          varchar(12) null,
  1806.          tot_pages     float,
  1807.          time_mins     float     null)
  1808.    
  1809.    /* Create table of column info for the table to be estimated */
  1810.    
  1811.    select length, type, name, offset
  1812.         into #col_table
  1813.              from syscolumns
  1814.                   where id = @table_id
  1815.    
  1816.    /* Look up the important values from this table */
  1817.    
  1818.    select @sum_fixed = isnull(sum(length),0)
  1819.         from #col_table
  1820.              where offset !< 0
  1821.    
  1822.    select @num_var = isnull(count(*),0), @sum_var = isnull(sum(length),0)
  1823.         from #col_table
  1824.              where offset < 0
  1825.                   and charindex(name, @cols_to_max) > 0
  1826.    
  1827.    select @num_var = @num_var + isnull(count(*),0),
  1828.     @sum_avgvar = isnull(sum(length / 2),0)
  1829.         from #col_table
  1830.              where offset < 0
  1831.                   and charindex(name, @cols_to_max) = 0
  1832.    
  1833.    /* Calculate the data page requirements */
  1834.    
  1835.    if @num_var = 0
  1836.         select @row_len = 4.0 + @sum_fixed
  1837.    else
  1838.         select @row_len = 8.0 + @sum_fixed + @sum_var +@sum_avgvar + @num_var
  1839.                        + (@sum_var +@sum_avgvar) / 256.0
  1840.    
  1841.    /* Allow for fill-factor if set to other than zero */
  1842.    
  1843.    if @fill_factor = 0
  1844.         select @temp = convert(float, @no_of_rows) *
  1845.              ( convert(float, @row_len) / convert(float, @page_size) )
  1846.    else
  1847.    begin
  1848.         select @temp = convert(float, @no_of_rows) /
  1849.              (convert(float, @page_size) * convert(float, @fill_factor) )
  1850.         select @temp = convert(float, @row_len) * @temp
  1851.    end
  1852.    
  1853.    /* Now add in allocation pages */
  1854.    select @temp = @temp +(@temp / 256.0)
  1855.    select @data_pages = @temp + 1.0
  1856.    if @data_pages < 8.0
  1857.         select @data_pages = 8.0
  1858.    
  1859.    insert #results values
  1860.         (@table_name, `data', 0, @data_pages, @data_pages * @page_K)
  1861.    
  1862.    /* See if the table has any indexes */
  1863.    
  1864.    select @index_id = min(indid)
  1865.         from sysindexes
  1866.              where id = @table_id
  1867.                   and indid > 0
  1868.    
  1869.    if @index_id = null /* We've finished if there are no indexes */
  1870.    begin
  1871.         select @msg = @table_name + ` has no indexes'
  1872.         print @msg
  1873.         select name, type, level,
  1874.              Pages = str(pages,12,0), Kbytes = str(Kbytes,12,0)
  1875.              from #results
  1876.    
  1877.         select Total_Mbytes = str(sum(Kbytes)/1000.0,15,0)
  1878.              from #results
  1879.    
  1880.         drop table #results
  1881.         return
  1882.    end
  1883.    
  1884.    select    @sum_fixed = 0,
  1885.         @sum_var = 0,
  1886.         @num_var = 0,
  1887.         @temp = 0
  1888.    
  1889.    /* For each index, calculate the important variables
  1890.    ** use them to calculate the index size, and print it */
  1891.    
  1892.    while @index_id != null
  1893.    begin
  1894.         select @index_name = name
  1895.              from sysindexes
  1896.                   where id = @table_id
  1897.                   and indid = @index_id
  1898.    
  1899.         if @index_id = 1
  1900.              select @index_type = `clustered'
  1901.         else
  1902.              select @index_type = `nonclustered'
  1903.    
  1904.         select    @num_var = 0,
  1905.              @sum_var = 0,
  1906.              @sum_fixed = 0
  1907.    
  1908.         select @i = 1
  1909.    
  1910.         /* Look up each of the key fields for the index */
  1911.    
  1912.         while @i <= 16
  1913.         begin
  1914.              select @key = index_col(@table_name, @index_id, @i)
  1915.    
  1916.              if @key = null
  1917.                   break
  1918.              else           /* Process one key field */
  1919.              begin
  1920.                   select @type = type, @length = length, @vartype = offset
  1921.                        from syscolumns
  1922.                             where id = @table_id
  1923.                             and name = @key
  1924.    
  1925.                   if @vartype < 0
  1926.                        select @num_var = @num_var + 1
  1927.                   else
  1928.                        select @sum_fixed = @sum_fixed + @length
  1929.    
  1930.                   if @vartype < 0     /* variable:check if in @cols_to_max */
  1931.                   begin
  1932.                        if charindex(@key, @cols_to_max) = 0
  1933.                         select @sum_var = @sum_var + (@length / 2)
  1934.                        else
  1935.                         select @sum_var = @sum_var + @length
  1936.                   end
  1937.              end
  1938.    
  1939.              select @i = @i + 1  /* Get next key field in this index */
  1940.         end
  1941.    
  1942.         /* Calculate the space used by this index */
  1943.    
  1944.         if @num_var = 0
  1945.              select @row_len = 5 + @sum_fixed
  1946.         else
  1947.              select @row_len = @sum_fixed + @sum_var + @num_var + 8
  1948.    
  1949.         if @index_id != 1   /* add row id for nc indexes */
  1950.              select @row_len = @row_len + 4
  1951.    
  1952.         select @level = 0
  1953.    
  1954.         /* Allow for fill-factor if set to other than zero */
  1955.    
  1956.         if @fill_factor = 0
  1957.              select @rows_per_page = @page_size / @row_len - 2
  1958.         else
  1959.              select @rows_per_page = @page_size / @row_len * @fill_factor
  1960.    
  1961.         if @rows_per_page > 256
  1962.              select @rows_per_page = 256
  1963.    
  1964.         /* For clustered indexes, the first level of index is based on the
  1965.         ** number of data pages.
  1966.         ** For nonclustered, it is the number of data rows     */
  1967.    
  1968.         if @index_id = 1
  1969.              select @next_level = @data_pages
  1970.         else
  1971.              select @next_level = @no_of_rows
  1972.    
  1973.         select @more = 1    /* Flag for end of index levels */
  1974.         while @more = 1
  1975.         begin
  1976.    
  1977.              /* calculate the number of pages at a single index level */
  1978.    
  1979.              select @temp = @next_level / convert(float, @rows_per_page)
  1980.    
  1981.              /* Add in a factor for allocation pages */
  1982.              if @temp > 200.0
  1983.                   select @temp = @temp + (@temp /256.0) + 1.0
  1984.    
  1985.              select @level_pages = @temp
  1986.    
  1987.              insert #results values
  1988.                   (@index_name, @index_type, @level, @level_pages,
  1989.                        @level_pages * @page_K)
  1990.    
  1991.              if @index_id != 1 and @level = 0 /* adjust NC non-leaf rows */
  1992.                   begin
  1993.                   select @row_len = @row_len + 4
  1994.    
  1995.                   /* Allow for fill-factor if set to other than zero */
  1996.    
  1997.                   if @fill_factor = 0
  1998.                        select @rows_per_page = @page_size/@row_len - 2
  1999.                   else
  2000.                        select @rows_per_page = @page_size/@row_len*@fill_factor
  2001.                   end
  2002.    
  2003.              if @rows_per_page > 256
  2004.                   select @rows_per_page = 256
  2005.    
  2006.              select @next_level = @level_pages
  2007.              select @level = @level + 1
  2008.    
  2009.              /* see if we can fit the next level in 1 page */
  2010.              if @rows_per_page >= @next_level
  2011.                   select @more = 0
  2012.         end
  2013.    
  2014.         /* Account for single root page */
  2015.         if @level_pages > 1
  2016.              insert #results values
  2017.                   (@index_name, @index_type, @level, 1, @page_K)
  2018.    
  2019.         /* Now look for next index id for this table */
  2020.    
  2021.         select @last_id = @index_id
  2022.         select @index_id = null
  2023.         select @index_id = min(indid)
  2024.              from sysindexes
  2025.                   where id = @table_id
  2026.                   and indid > @last_id
  2027.    
  2028.    end
  2029.    
  2030.    select name, type, level, Pages = str(pages,12,0), Kbytes = str(Kbytes,12,0)
  2031.    from #results
  2032.    
  2033.    select Total_Mbytes = str(sum(Kbytes)/1000.0,15,0)
  2034.    from #results
  2035.    
  2036.    drop table #results
  2037.    drop table #col_table
  2038.    
  2039.    return
  2040.    /* ### DEFNCOPY: END OF DEFINITION */
  2041.    
  2042.    
  2043.    
  2044.    ++++++++++++++++++++++++++++++++++++++++++++++
  2045.    Q10. What causes a database to be marked SUSPECT and can I recover
  2046.       a database that comes up marked `SUSPECT'?
  2047.  
  2048.    Answer:    My previous response to this question contained BAD INFORMATION
  2049.    that I want to clear up at this point.  The previous example recommended the
  2050.    use of the dbcc command 'save_rebuild_log'.  DO NOT DO THIS.  This command
  2051.    does NOT rebuild your log, it just creates a NEW, EMPTY one, and leaves the
  2052.    old one in the database, if possible, for Technical Support consultation as
  2053.    part of a recovery plan.   The intended use of this utility is to move the
  2054.    log aside before initial patching, so checkpoints may be made without
  2055.    disturbing a log that will be consulted later on for more clues into the
  2056.    failure and the ensuing recovery.  The previous post implied that this
  2057.    command somehow rebuilt the transaction log.  NOT!  This, by the way, is a
  2058.    good example of why only DOCUMENTED dbcc commands should be used (See earlier
  2059.    question on undocumented dbcc commands).
  2060.  
  2061.    A database is marked suspect when the integrity of the database is
  2062.    questionable.  The damage was caused at some previous time by a software or
  2063.    hardware problem.  Run the dbcc commands checktable or checkdb to determine
  2064.    the extent of the damage.
  2065.  
  2066.    There are occasional situations in which a database will be marked suspect
  2067.    even though there is nothing wrong with the database.  I ran into this
  2068.    situation as an example:
  2069.  
  2070.         A PC-client is rebooted during an update leaving an uncommitted
  2071.         transaction in the transaction log.  Eventually the transaction log
  2072.         fills up even though it is dumped regularly.  The sa, aware of the
  2073.         problem, decides to cycle the server after dumping the transaction log
  2074.         had minimal effect (only the inactive portion of the log was dumped).
  2075.         When the database comes up, it is marked suspect.  It is marked suspect
  2076.         because the server is unable to do a checkpoint on recovery due to the
  2077.         fact that the transaction log is full.  This is a recoverable situation.
  2078.  
  2079.    The following steps allow a suspect database to be recovered.
  2080.  
  2081.    1. Start the server and watch the database come up "suspect"
  2082.  
  2083.    2. execute isql as "sa"
  2084.          >   sp_configure "allow",1
  2085.          >   go
  2086.          >   reconfigure with override
  2087.          >   go
  2088.          >   update master..sysdatabases    /* Bypass recovery on startup */
  2089.              set status = -32768
  2090.              where name=<suspect_db_name>
  2091.          >   go
  2092.  
  2093.    3. Shutdown and restart the server.  The server will come up and the
  2094.       database will not be marked suspect.
  2095.  
  2096.    4. Execute isql as "sa"
  2097.         >    use <suspect_db_name>
  2098.         >    go
  2099.         >    update master..sysdatabases /* Reset the database status */
  2100.              set status=0
  2101.              where name='<suspect_db_name>'
  2102.         >    go
  2103.         >    sp_configure "allow",0
  2104.         >    go
  2105.         >    reconfigure
  2106.         >    go
  2107.  
  2108.    5. Execute dbcc checkdb and checkcatalog  to validate the integrity of the
  2109.       database.  If the database passes these checks, you can continue safely.
  2110.       DO NOT ASSUME that the database is OK just because you were able to make
  2111.       it recover by changing the status flag.
  2112.  
  2113.    6. If dbcc indicates problems, you will need to COPY OUT YOUR DATA ASAP
  2114.       (bcp), and REBUILD THE DATABASE.  You may not even be able to do this, in
  2115.       which case you must restore your database from previous database and
  2116.       transaction log dumps.
  2117.    
  2118.    ++++++++++++++++++++++++++++++++++++++++++++++
  2119.    Q11. My database tables often get locked by the client's hung
  2120.       workstation. Is there a way that I can unlock those locked tables?
  2121.  
  2122.    Answer:    The most common reasons for this kind of behavior is a PC client
  2123.    where the user in the middle of the query assumes he has had enough and
  2124.    reboots the PC. This will leave a sleeping process with all locks on the
  2125.    table being held as is. A kill command will not be able to kill this process
  2126.    since an attention cannot be raised on a sleeping process. The only way to
  2127.    get around this problem is to make sure that users do not reboot their
  2128.    machines in the middle of a query.
  2129.  
  2130.    Also if you are using Q+E you might want to change cancel = 1 your qex.ini /
  2131.    qe.ini depending on the version of Q+E. This will force a dbcancel to be
  2132.    issued when the query window is closed. If a dbcancel is not issued then a
  2133.    call to dbclose is made. Most often than not the connection is not closed
  2134.    properly since there is pending data on that socket.
  2135.  
  2136.    One other option is to set the keepalive parameter on the server machine to a
  2137.    fairly low value if this is a configurable parameter on your platform. The
  2138.    result of setting this option is that at the specified time frame if there is
  2139.    no response from the client socket the server will drop that process. This
  2140.    will clear all the locks that are being held by that process.
  2141.    
  2142.    
  2143.    ++++++++++++++++++++++++++++++++++++++++++++++
  2144.    Q12. Does the server sort order affect performance? Is binary sort order
  2145.       the fastest way?
  2146.  
  2147.    Answer:    Yes, binary sort order is fastest because no lookup is needed.
  2148.    Please keep in mind that sort order only has impact on operations that
  2149.    involve comparison of character data like creating indexes and evaluating
  2150.    qualifications on character values.  (Most of the performance gain of binary
  2151.    sorting is that binary comparisons are native to all computers; all other
  2152.    sort orders involve algorithmic binary comparisons of multi-byte abstract
  2153.    data types.)
  2154.  
  2155.    Sort orders are defined in .srt files found under in the character set
  2156.    directories. There are three values associated with each character. Looking
  2157.    at the character file defining the sort order, you can correlate those three
  2158.    values with the placement of that character in the file.
  2159.  
  2160.       Primary sort value is determined by the line in the file.
  2161.  
  2162.       Secondary sort value is determined by the position within the line.
  2163.  
  2164.       Tertiary sort value is also dependent on the position of the character on
  2165.       the line.
  2166.  
  2167.    Some examples from files in the iso_1 directory of a 4.9.1 installation:
  2168.  
  2169.    dictionary.srt
  2170.    ==============
  2171.    char=0x41,0x61,0xC0,0xE0,0xC1,0xE1,0xC2,0xE2,0xC3,0xE3,0xC4,0xE4,0xC5,0xE5
  2172.     ;A, a, A-grave, a-grave, A-acute, a-acute, A-circumflex, a-circumflex,
  2173.     ;A-tilde, a-tilde, ;A-diaeresis, a-diaeresis, A-ring, a-ring
  2174.    char = 0x42, 0x62 ;letter B, b
  2175.  
  2176.    With dictionary sorting, every "a" is sorted before every "b" and among
  2177.    different "a" values there is sorting based on the different secondary sort
  2178.    values.
  2179.    
  2180.    nocase.srt
  2181.    ==========
  2182.    char=0x41=0x61,0xC0=0xE0,0xC1=0xE1,0xC2=0xE2,0xC3=0xE3,0xC4=0xE4,0xC5=0xE5
  2183.     ;A, a, A-grave, a-grave, A-acute, a-acute, A-circumflex, a-circumflex,
  2184.     ;A-tilde, a-tilde, ;A-diaeresis, a-diaeresis, A-ring, a-ring
  2185.    char = 0x42=0x62 ;letter B, b
  2186.  
  2187.    With case insensitivity, "A" and "a" have the same secondary as well as
  2188.    primary sort order. That is denoted in the file by the equal sign between the
  2189.    two hex values for their encondings in the ISO 8859-1 character set. The case
  2190.    insensitivity also applies to names in the SQL Server so you could not have
  2191.    two objects in the same database with names differing only in case, such as
  2192.    SuperBowl and SuperbOwl.
  2193.  
  2194.    noaccent.srt
  2195.    ============
  2196.    char=0x41=0x61=0xC0=0xE0=0xC1=0xE1=0xC2=0xE2=0xC3=0xE3=0xC4=0xE4=0xC5=0xE5
  2197.     ;A, a, A-grave, a-grave, A-acute, a-acute, A-circumflex, a-circumflex,
  2198.     ;A-tilde, a-tilde, ;A-diaeresis, a-diaeresis, A-ring, a-ring
  2199.    char = 0x42=0x62 ;letter B, b
  2200.  
  2201.    With no accent, any "a" is equal to another. This could be useful if an
  2202.    application searches on last names and the entry is not exactly correct, like
  2203.    an A-grave instead of A-acute. This sort order is new with the 4.9.1. It is
  2204.    considered very useful by some European customers.
  2205.  
  2206.    The only difference between the files nocase.srt and nocasepref.srt is the
  2207.    line "preference=true" in the latter. With preference, "A" is equal to "a".
  2208.    However, in the results of a query with ORDER BY on a character column, "A"
  2209.    will precede "a". This has important performance implications. An index on
  2210.    character data can not ensure values are already in the order you prefer and
  2211.    comparisons using tertiary sort values must be done in a worktable.
  2212.  
  2213.    Robert Garvey 
  2214.    
  2215.    ++++++++++++++++++++++++++++++++++++++++++++++
  2216.    Q13. Does Sybase have a memory limit?
  2217.  
  2218.    Answer:    Sybase has no memory limit. The typical problem with getting the
  2219.    memory you want on UNIX is due to the OS's insistence that there be enough
  2220.    swap space to accommodate the entire data space of a process at startup time.
  2221.    UNIX doesn't want to give out memory it cannot in theory write *entirely* to
  2222.    disk at some point. Thus, when SQL Server asks for 16MB of memory, for
  2223.    example, unless you have that much swap space available, the request will be
  2224.    denied, and the server will live with less or abort. Run the utility your
  2225.    UNIX provides to tell how much swap is in use when you have this memory
  2226.    problem with SQL Server. If it varies a lot, consider putting your RUNSERVER
  2227.    command file in your system startup procedure, so SQL Server can start up
  2228.    when memory is most clear. If your swap space is often lacking in large
  2229.    amounts of space regardless of other system activity, you'll need to add
  2230.    more. The general rule is to have between 2 and 3 times physical memory size
  2231.    in swap space.
  2232.  
  2233.    Benjamin von Ullrich
  2234.    
  2235.  
  2236. ----------------------------------------------------------------------
  2237. 2.9.     Sybase Performance Tuning
  2238.    
  2239.    
  2240.    ++++++++++++++++++++++++++++++++++++++++++++++
  2241.    Q1.  How much overhead do variable size and NULL columns require?
  2242.  
  2243.    Answer:    The Sybase Performance and Tuning class notes give the following
  2244.    information:
  2245.  
  2246.    An additional 5 bytes are used if there are ANY variable length fields.
  2247.  
  2248.    An additional 1 byte is used for each variable length field.
  2249.  
  2250.    Therefore, if you have two variable length fields, you have an extra seven
  2251.    bytes per row. Also, note that any field defined as allowing nulls is treated
  2252.    as variable length.
  2253.    
  2254.    
  2255.    ++++++++++++++++++++++++++++++++++++++++++++++
  2256.    Q2.  How are null values stored?  How does Sybase distinguish between an
  2257.       integer and a null value for an integer, and so forth?
  2258.  
  2259.    Answer:    Sybase stores NULL values as zero length columns of the required
  2260.    datatype.  The first byte represents the length of the field.  That is how
  2261.    the server knows whether a field is NULL, i.e., the length of the field is 0.
  2262.    In the case of datatypes that are of fixed length, such as Integer, and
  2263.    therefore do not contain a length prefix, Sybase has defined a set of
  2264.    variable length equivalent datatypes to use when such columns are defined as
  2265.    allowing nulls.  Thus, any column that allows nulls is by definition of
  2266.    variable length (this can have a significant impact on the way the optimizer
  2267.    works in certain situations).
  2268.  
  2269.    To get a quick idea of how large a table-row will be, you can look in
  2270.    sysindexes at the max/min values of the table if it is created.  It wont give
  2271.    you all that you need but will give you best/worts case row-sizes, which in
  2272.    many cases is good enough.
  2273.    Thanks to Howard Michalski
  2274.    
  2275.    
  2276.    ++++++++++++++++++++++++++++++++++++++++++++++
  2277.    Q3.  How are text and image types stored?
  2278.  
  2279.    Answer:    Text and image data are stored on whole data pages for any value
  2280.    or amount of data other than NULL.  A pointer to the head of a chain of pages
  2281.    is stored in the regular data pages in the table whenever a text or image
  2282.    value is inserted into the table.  If NULL is inserted, no text or image
  2283.    pages are allocated, and thus no internal fragmentation.
  2284.    Keep in mind that pages are always allocated and deallocated to/from a table
  2285.    in extents of 8 pages, so initial column allocations take a good deal of
  2286.    space.
  2287.  
  2288.    Searching text (with LIKE) takes ONE LOCK PER PAGE.  If your server is still
  2289.    configured for the default number of locks (5000), you will quickly run out
  2290.    of locks on your whole SQL Server unless you "up" this value.  TEXT is not
  2291.    meant to search -- use some other table or summary field to describe the
  2292.    relevant contents of text field(s) you must search.
  2293.    
  2294.    
  2295.    ++++++++++++++++++++++++++++++++++++++++++++++
  2296.    Q4.  How do I interpret the cryptic output of 'set showplan on'?
  2297.  
  2298.    Answer:    The 'set' commands provide invaluable information about how a
  2299.    particular batch or query is going to execute.  The 'set showplan on' command
  2300.    displays a number of phrases that help to determine what decisions the query
  2301.    optimizer has made.
  2302.  
  2303.    Most of the usefulness of this output is the index selection.  Look for index
  2304.    usage that is consistent with what you would expect, knowing the nature of
  2305.    clustered versus non-clustered indexes.  This is a long story, and requires
  2306.    in-depth knowledge of these index types and the optimizer's related choices.
  2307.    Following is a list of typical phrases and the meaning of each of these
  2308.    phrases.  (This is not an exhaustive list and will be more fully developed in
  2309.    future releases.):
  2310.    
  2311.    1. FROM TABLE <tablename> Nested Interation Table Scan
  2312.  
  2313.         This indicates that the server is going to access every single row in
  2314.         the table to perform this query.  Every single page will be read.   NOTE
  2315.         -- Don't always be alarmed by every instance of Table Scan.  Tables
  2316.         which are less than one extent (16K = 8 pages at 2K per page) in size
  2317.         are ALWAYS scanned.  Worktables, which are created on the fly, tend to
  2318.         stay in cache, so these are less of a performance hit than tables scans
  2319.         on user-defined tables.
  2320.    
  2321.    2. FROM TABLE <tablename> Nested iteration Index: <indexname>
  2322.  
  2323.         The server is going to access rows in this table using the explicitly
  2324.         named index.  The server reads only those pages on which the non-
  2325.         clustered index indicates a row exists.  Only the appropriate portions
  2326.         of the table are accessed.
  2327.    
  2328.    3. FROM TABLE <tablename> Nested iteration using Cusltered Index.
  2329.  
  2330.         The server is going to access rows in this table using the clustered
  2331.         index.  The name of this index will not be explicitly specified, but
  2332.         there can only be one clustered index per table.  The server reads only
  2333.         those pages on which a row exists.  Often, there are more "hits" per
  2334.         page retrieved with a clustered index than a nonclustered since the data
  2335.         is physically ordered according the the declaration of the clustered
  2336.         index.  The fact that the clustered index was selected by the plan
  2337.         indicates that rows of similar nature are being retrieved and those rows
  2338.         are positioned physically close to one another on the disk.
  2339.    
  2340.    
  2341.    ++++++++++++++++++++++++++++++++++++++++++++++
  2342.    Q5.  How does the query optimizer work? Does the ordering of tables in
  2343.       the from clause or the conditionals in the where clauses affect the
  2344.       performance of the query?
  2345.  
  2346.    Answer:    Normally, the ordering in the from clause and the where clause
  2347.    will not affect the performance of the query. The only time that it can have
  2348.    this effect is if there is more than one query plan that the optimizer
  2349.    estimates will take exactly the same time as the best plan. In this case, the
  2350.    optimizer will choose the first of these plans that it sees. The ordering in
  2351.    the from and where clauses will change which of these plans it sees first.
  2352.    Only in this case will the ordering affect the query plan.
  2353.    This will affect the performance if some of these plans with identical cost
  2354.    estimates are significantly faster or slower than the others. This should not
  2355.    happen - the optimizer's cost estimates should reflect the true cost of
  2356.    running the query. But in practice, the optimizer sometimes has a bug or
  2357.    other problem that causes the cost estimates to be inaccurate.
  2358.    So, for the ordering in the from or where clause to affect the performance,
  2359.    the following must be true:
  2360.  
  2361.       Two or more query plans have the same cost estimate, and this is the
  2362.       lowest cost estimate for the query.
  2363.  
  2364.       A bug in the optimizer causes one of these identical cost estimates to be
  2365.       significantly inaccurate.
  2366.  
  2367.    Needless to say, these two things don't happen very often at the same time.
  2368.  
  2369.    Jeff Lichtman
  2370.    
  2371.    
  2372.    ++++++++++++++++++++++++++++++++++++++++++++++
  2373.    Q6.  Can I force the optimizer to access tables in a certain order or to
  2374.       use a particular index?
  2375.  
  2376.    Answer:    Yes, if one of your problems is that tables are being accessed in
  2377.    the wrong order (the showplan is screwed up) then you can try the following:
  2378.  
  2379.         set forceplan on
  2380.         
  2381.         select . . ..
  2382.         from table_a a, table_b b, table_c c
  2383.         where . . .
  2384.         
  2385.         set forceplan off
  2386.  
  2387.    The 'set forceplan on/off' will tell the optimizer to access the tables in
  2388.    the order that they've been listed in the 'from' clause. Mind you, you have
  2389.    to make this determination as to which tables should come first in the list.
  2390.    You can force the server to use a particular index by putting the index id
  2391.    ('indid' from sysindexes) in parentheses after the table name in the 'from'
  2392.    clause, but I recommend reconfiguring the query so that the optimizer can
  2393.    figure out which index to use on its own. Usually you can specify enough
  2394.    relationships to "nudge" the optimizer the right way.
  2395.  
  2396.    Steve Medin had these comments on this topic:
  2397.  
  2398.    Force index is implemented by placing a number after the table name in the
  2399.    from clause. The number refers tothe index that will be used by the
  2400.    optimizer, where the clustered index is always (1) and the nonclustered
  2401.    indices are sequenced in the order of your DDL create index statements, or
  2402.    chronologically if you have several scripts that build your indices. The
  2403.    possibility that a nonclustered index will get out of sequence is fairly
  2404.    high, but this feature can be quite useful if the optimizer refuses to use
  2405.    the clustered index on a table and you have provided where criteria for all
  2406.    the index columns. To force use of the clustered index on you ORDERS table,
  2407.    try:
  2408.         ...
  2409.         FROM ORDERS(1),
  2410.         ...
  2411.    This, again, can be useful when you can make an assumption about a table's
  2412.    size and you would rather tablescan a tiny table than get a clustered index
  2413.    iteration on the larger table that will not use the clustered index.
  2414.    Try these out with showplan and stats io on. If you're really daring, try
  2415.    putting them in live application code. when you call tech support, they will
  2416.    tell you to remove the statements and recreate the problem.  Tech Support
  2417.    will not refuse to open a case over subjective judgements over the use of
  2418.    Sybase software.  However, if a user is insisting that the *undocumented*
  2419.    query optimization rules behave in some particular manner, especially when
  2420.    the *undocumented* forceindex feature is used, it is understandable that
  2421.    Sybase refuse to 'fix' this 'bug'.
  2422.    
  2423.    ++++++++++++++++++++++++++++++++++++++++++++++
  2424.    Q7.  Does dropping an index cause recompilation of a stored procedure?
  2425.  
  2426.    Answer:    Yes, dropping an index will cause recompilation of stored
  2427.    procedures which `touch' the indexed table. Adding an index, or updating
  2428.    statistics will NOT.
  2429.  
  2430.    Use sp_recompile <tablename> to force all objects referencing tablename to
  2431.    recompile on their next execution.
  2432.    
  2433.    ++++++++++++++++++++++++++++++++++++++++++++++
  2434.    Q8.  Does the time for a select that yields 1000 rows from a table of
  2435.       10,000 differ much from the same select when the table contains 100,000
  2436.       rows?
  2437.  
  2438.    Answer:    Table size would not be a factor iff you have a clustered index on
  2439.    the columns used to locate the SELECTed rows. Since clustering orders the
  2440.    rows by the columns which make up the index keys, we would locate the first
  2441.    data page where the key matches the qualification, and follow the page chain
  2442.    until the next key is encountered, and stop scanning. This all depends on the
  2443.    type of qualification, but this illustrates that a clustered index orders a
  2444.    table such that any part of it is just as locatable as any other, regardless
  2445.    of total size. B-trees properly maintained are never very deep, so index
  2446.    depth is never an issue in SQL Server.
  2447.  
  2448.    Actually, you could also achieve like response time on a small vs. large
  2449.    table if the result columns of the query are covered by a nonclustered index.
  2450.    This is a poor way to accomplish this, however, since non-clustered indexes
  2451.    on multi-million row tables take up a good deal of room, but this can be your
  2452.    only alternative if you are already using the clustered index for something
  2453.    else and can't change it.
  2454.  
  2455.    Be careful not to add so much to the table if it is wide (has many fields,
  2456.    and/or many large character fields). Normalize out these "big text" fields to
  2457.    other table(s) that you only look at when you need to. some of the best
  2458.    performance gains can be had by having more rows per page.
  2459.  
  2460.    Benjamin von Ullrich
  2461.    
  2462.    
  2463.    ++++++++++++++++++++++++++++++++++++++++++++++
  2464.    Q9.  Is there a way to gather performance statistics besides using
  2465.       sp_monitor?
  2466.  
  2467.    Answer:    Sybase is now offering a product called SQL Monitor.  It is a
  2468.    separate server that monitors shared memory and provide detailed information
  2469.    on server internals.
  2470.  
  2471.    There is also a PC based tool called SQL Watch by PACE Systems that is pretty
  2472.    good.
  2473.  
  2474.    You may also want to check out Xsybmon by David Joyner.  This is a free
  2475.    application that continuously executes the stored procedure sp_monitor and
  2476.    displays the results.  See section 9.3 for details on this product.
  2477.  
  2478.    Version 4.8 and above of the SQL Server also offer the dbcc command
  2479.    'monitor'.  It is used in the following manner:
  2480.  
  2481.         /* Zero all of the counters */
  2482.         dbcc monitor("clear", "all", "on")
  2483.         go
  2484.         /* Wait during the sampling period, typically 60 seconds to allow for
  2485.         accumulation of data */
  2486.         
  2487.         /* Sample the counters */
  2488.         dbcc monitor("sample", "all", "on")
  2489.         
  2490.         /* View the counters */
  2491.         dbcc traceon(8399) /* Enable useful names */
  2492.         go
  2493.         
  2494.         select field_name, group_name, value
  2495.         from sysmonitors
  2496.         [where value != 0]
  2497.  
  2498.    Various monitoring groups will be displayed.
  2499.    
  2500.    ++++++++++++++++++++++++++++++++++++++++++++++
  2501.    Q10. Does Sybase do page or row level locking?
  2502.  
  2503.    Answer:    Sybase does page level locking and under certain circumstances
  2504.    will escalate locks to the table level.  If an update is issued that will
  2505.    require more than about 200 exclusive page locks to be acquired it will try
  2506.    to escalate its lock to the whole table rather than the individual pages.
  2507.    The escalation attempt may not succeed and thus locking may well continue at
  2508.    the page level even in this case.
  2509.  
  2510.    Thanks to David Shanahan
  2511.    
  2512.    ++++++++++++++++++++++++++++++++++++++++++++++
  2513.    Q11. What types of locks can be issued and what do they mean?
  2514.  
  2515.    Answer:    Locks can be placed on a page, a table, or an extent.  (An extent
  2516.    is a group of 8 database pages that are being either allocated or
  2517.    deallocated.)  Sybase does not support row level locking.
  2518.    Exclusive locks, beginning with the prefix 'Ex_' are set so that no other
  2519.    transaction can acquire a lock of any kind on the locked objects until the
  2520.    original lock is released at the end of the transaction.
  2521.    Shared locks, beginning with the prefix 'Sh_', are issued for non-update or
  2522.    read operations.  When a shared lock is applied to a table or page, other
  2523.    transactions can also acquire a shared lock even though the first transaction
  2524.    has not completed.  No transaction can acquire an exclusive lock until all
  2525.    shared locks on it have been released.
  2526.  
  2527.    An intent lock is represents the intention to acquire a shared or exclusive
  2528.    lock on a page.
  2529.  
  2530.    An extent lock is used when a CREATE or DROP command is running, or while an
  2531.    INSERT operation that requires new pages for data or index entries is
  2532.    running.
  2533.  
  2534.    A demand lock prevents any additional shared locks from being issued on an
  2535.    object.  This is required since shared locks can overlap one another and
  2536.    force a write transaction to wait indefinitely.  The demand lock is issued
  2537.    after a write operation waits on four successive read locks to complete.
  2538.    The locks which are currently being enforced can be monitored using sp_lock.
  2539.    This shows which spid has which objects locked in which database and the type
  2540.    of lock that is in place.
  2541.  
  2542.    The following types of locks are reported by the sp_lock stored procedure.
  2543.    (The list below was generated by issuing the SQL statement "select name from
  2544.    master.dbo.spt_values where type = 'L' order by name"):
  2545.         Ex_extent
  2546.         Ex_extent-blk
  2547.         Ex_extent-demand
  2548.         Ex_intent
  2549.         Ex_intent-blk
  2550.         Ex_intent-demand
  2551.         Ex_page
  2552.         Ex_page-blk
  2553.         Ex_page-demand
  2554.         Ex_table
  2555.         Ex_table-blk
  2556.         Ex_table-demand
  2557.         Sh_extent
  2558.         Sh_extent-blk
  2559.         Sh_extent-demand
  2560.         Sh_intent
  2561.         Sh_intent-blk
  2562.         Sh_intent-demand
  2563.         Sh_page
  2564.         Sh_page-blk
  2565.         Sh_page-demand
  2566.         Sh_table
  2567.         Sh_table-blk
  2568.         Sh_table-demand
  2569.         Update_page
  2570.         Update_page-blk
  2571.         Update_page-demand
  2572.    
  2573.    
  2574.    ++++++++++++++++++++++++++++++++++++++++++++++
  2575.    Q12. What exactly does the HOLDLOCK keyword do?
  2576.    
  2577.    Answer:    The HOLDLOCK keyword is used in the from clause of a select
  2578.    statement to make a shared lock more restrictive.  Normally, a shared lock is
  2579.    released as soon as the required table, view or page is no longer needed,
  2580.    regardless of whether or not the transaction is complete.  Using a HOLDLOCK
  2581.    on a particular table extends the reach of the shared lock to the end of the
  2582.    transaction in which it is involved, even if the statement no longer requires
  2583.    the lock.  This assures read consistency within a transaction when there is
  2584.    the possibility that another user might update the table between two
  2585.    successive reads of the data.  In other words, if a HOLDLOCK is NOT used,
  2586.    there is no guarantee that a row that is read twice within a transaction will
  2587.    result in the same value both times.
  2588.    
  2589.    It is important to remember that the HOLDLOCK only issues a shared lock and
  2590.    NOT and exclusive lock.  Other users can also issue a shared lock and read
  2591.    through your shared lock to obtain the same value; therefore, you should not
  2592.    base an update on a value obtained through the use of a shared lock.
  2593.    
  2594.    For example, DO NOT DO THIS...
  2595.         begin transaction
  2596.         select col1 from table HOLDLOCK where conditions
  2597.         update col1 set col1 = col1 + 1 from table where conditions
  2598.         commit transaction
  2599.    
  2600.    You might expect this to prevent others from reading the same column you are
  2601.    planning on changing, but this is not the case.  There is a possibility that
  2602.    another user may read and update the column based on the value they read,
  2603.    possibly overwriting the change you just made.
  2604.    
  2605.    The solution to the above example is to update on column first, thereby
  2606.    obtaining an exclusive lock through the end of the transaction, as in
  2607.         begin transaction
  2608.         update col1 set col1 = col1 + 1 from table where conditions
  2609.         select col1 - 1 from table where conditions
  2610.         commit transaction
  2611.    
  2612.    
  2613.    ++++++++++++++++++++++++++++++++++++++++++++++
  2614.    Q13. Why, when a stored procedure is forced to compile, does the query
  2615.       plan grow eventually causing the stored procedure to crash?
  2616.  
  2617.    Answer:    Any of the following will cause a stored procedure to grow when it
  2618.    is recompiled:
  2619.  
  2620.    1.   One of the tables used in the procedure is dropped and recreated.
  2621.  
  2622.    2.   A new rule or default is bound to one of the tables or the user runs
  2623.    sp_recompile on one of the tables.
  2624.  
  2625.    3.   The database containing the stored procedure is re-loaded.
  2626.    Other things causing a stored procedure to be re-compiled will not cause it
  2627.    to grow.  For example, dropping an index on one of the tables used in the
  2628.    procedure or doing EXEC WITH RECOMPILE.
  2629.  
  2630.    The difference is between simple recompilation and re-resolution. Re-
  2631.    resolution happens when one of the tables changes in such a way that the
  2632.    query trees stored in sysprocedure may be invalid.  The datatypes, column
  2633.    offsets, object ids or other parts of the tree may change.  In this case, the
  2634.    server must re-allocate some of the query tree nodes.  The old nodes are not
  2635.    de-allocated (there is no way to do this within a single procedure header),
  2636.    so the procedure grows.
  2637.  
  2638.    In time, trying to execute the stored procedure will result in a 703 error
  2639.    about exceeding the 64 page limit for a query.
  2640.  
  2641.    System 10 Notes:
  2642.  
  2643.    1.In System 10, the server will automatically compress the stored procedures
  2644.      upon recompilation, therefore, the above problems will be fixed.
  2645.  
  2646.    2.There is no longer this page limit on the size of stored procedures.  They
  2647.      can grow indefinitely until the procedure cache configured is depleted.
  2648.  
  2649.    Thanks to Andrew Fergusen
  2650.    
  2651.    
  2652.    ++++++++++++++++++++++++++++++++++++++++++++++
  2653.    Q14. What is a segment and why should I use one?
  2654.    
  2655.    Answer:    When using segments to optimize a database's performance, there
  2656.    are some things to keep in mind:
  2657.    
  2658.    1.Contention with the default and system segments.
  2659.    
  2660.    2.Recovery
  2661.  
  2662.    Care must be taken to avoid contention with the default and system segments.
  2663.    Typically, when the decision has been made to assign a table or index to a
  2664.    perticular database segment the intention is to reserve that segment's use to
  2665.    operations on  a particular object.  When createing the database the 'system'
  2666.    and 'default' segments will point to all available 'non-logsegment' devices.
  2667.    This means that if one creates a user segment, by default the devices it
  2668.    point so will also be pointed to by the 'system' and 'default' segments.  To
  2669.    eliminate the risk of the user segment filling up, or contention on the
  2670.    devices from other objects in the 'default/system' realm use 'sp_dropsegment'
  2671.    to remove the "maps" to those devices.  For example:
  2672.  
  2673.         create database USERDB on data1=10, data2=10, data3=10
  2674.              log on log1=20
  2675.         go
  2676.         use USERDB
  2677.         go
  2678.         exec sp_dropsegment "default", data3
  2679.         exec sp_dropsegment "system", data3
  2680.         go
  2681.         sp_addsegment "seg1", data3
  2682.         go
  2683.         .
  2684.         .
  2685.         .
  2686.         create table TABLE1 (i int, date datetime)
  2687.         on seg1
  2688.         go
  2689.  
  2690.    This gives TABLE1 complete "ownership" of device 'data3'.  Keep in mind that
  2691.    when a table/index is created its growth is restricted to the space available
  2692.    within its segment's "domain".  In this example, TABLE1 can grow no larger
  2693.    than ~10 Meg.  This example brings up an interesting footnote.  A database
  2694.    will allocate space on its assigned devices in order by their NAME.  In this
  2695.    case, the system tables for USERDB were create on device data1 ( the first
  2696.    device in the system segment - which, BTW, pointed to data1, 2, and 3 up to
  2697.    the point where we dropped the map to data3).  If we were to create segment
  2698.    'seg1' as mapped to device 'data1' TABLE1 would "share" a portion of 'data1'
  2699.    with the system tables that were created there during the CREATE DATABASE
  2700.    exeution.  The system tables would "grow" onto devices in the system segments
  2701.    "domain", but would be "anchored" on 'data1'.
  2702.  
  2703.    Now with regards to item number 2, recovery.  When restoring from a database
  2704.    dump it is important to remember that the dump will restore the segments but
  2705.    NOT their mappings.  This is not an issue if you are restoring over the same
  2706.    database from which the dump was made, but when loading onto a new database
  2707.    the segment's maps must be rebuilt.
  2708.  
  2709.    If a dump was taken of USERDB (above) and loaded onto a database (called
  2710.    NEWUSERDB) segment 'seg1' would exist but its map to device 'data3' would
  2711.    not. [this supports dumps across servers without dependency on device names,
  2712.    etc.]  An extra step will be to rebuild the logical-to-logical-tophysical
  2713.    mapping of 'seg1' to the equivalent 'data3'.  To do this, proced as follows:
  2714.  
  2715.         /* The new database, created with equal fragment mappings , but on
  2716.         different device names */
  2717.         create database NEWUSERDB on data10=10, data20=10, data30=10
  2718.              log on log10=20
  2719.         go
  2720.         load database NEWUSERDB from some_dump
  2721.         go
  2722.         use NEWUSERDB
  2723.         go
  2724.         exec sp_dropsegment "default", data30
  2725.         exec sp_dropsegment "system", data30
  2726.         go
  2727.         sp_extendsegnemt seg1, data3
  2728.         go
  2729.  
  2730.    Note that 'seg1' exists after the load, but has no maps.  Also note that the
  2731.    re-mapping of 'seg1' could have taken place before the load database command.
  2732.    Procedure sp_extendsegment will also work on a database that has been created
  2733.    using the FOR LOAD option.
  2734.  
  2735.    The easiest way to picture all of this is to look at the schema diagrams that
  2736.    outline the server's system tables (master versus userdb).  Segment info on a
  2737.    particular database is kept in BOTH the user and master databases.  The user
  2738.    database maintains object mappings to a segment and the master database
  2739.    maintains segment mappings to a device (or devices).
  2740.    
  2741.    Provided by Howard Michalski
  2742.    
  2743.    
  2744.    ++++++++++++++++++++++++++++++++++++++++++++++
  2745.    Q15. What determines whether an update will be performed 'in place' or
  2746.       deferred?
  2747.  
  2748.    Answer:    Presence or absence of varchar columns does not affect whether the
  2749.    server does a direct (in-place) or deferred (delete/reinsert) update.  As of
  2750.    this writing, the rules for doing direct updates are:
  2751.    
  2752.    1.  If multiple columns are being updated, they must be contiguous.
  2753.  
  2754.    2. The column(s) being updated must all be fixed length -- the row may not
  2755.       change size because of the update.
  2756.  
  2757.    3. Exactly one row must be affected, AND SQL Server must know this at the
  2758.       beginning of the query.
  2759.  
  2760.    4. No column being updated may participate in the index that was used to
  2761.       find the row.
  2762.  
  2763.    5. No update triggers may be present on the table being updated.
  2764.    
  2765.    Any update that doesn't follow all the rules is deferred, not direct.
  2766.    
  2767.    (Note: performance work is presently being done that may eventually relax
  2768.    some of these restrictions.  However, these are the current rules.)  If these
  2769.    rules make it sound like almost all updates are deferred rather than direct
  2770.    ... guess what?
  2771.    
  2772.    [By the way.  In a direct update, we need to update only those indexes that
  2773.    actually refer to the columns being changed.  Deferred updates, on the other
  2774.    hand, require that we update   every index referring to the row.]
  2775.    
  2776.    Thanks to Elton Wildermuth
  2777.    
  2778.    
  2779.    ++++++++++++++++++++++++++++++++++++++++++++++
  2780.    Q16. How does altering a database table to add a new column affect the
  2781.       storage of the affected table?
  2782.    
  2783.    Answer:    No rows in your table are changed as a result of ALTER TABLE.  The
  2784.    only thing that happens is that the table's schema is updated to reflect the
  2785.    extra column.  That column is NULL in all presently existing rows, and we can
  2786.    tell that without making any changes to the data rows.
  2787.    
  2788.    What can take massive amounts of time, though, is the subsequent UPDATE that
  2789.    stuffs data into all those previously NULL columns.  Depending how full each
  2790.    page is, there can be a huge storm of page splits.  Also, note that by the
  2791.    rules (2 and 3), all those updated rows get deleted, then reinserted.
  2792.    Thanks to Elton Wildermuth
  2793.    
  2794.    How do I delete a column from a table?
  2795.    Answer:  Sybase doesn't let you "alter table drop <column>".  You must make
  2796.    of new copy of the table, excluding the desired column.
  2797.    
  2798.  
  2799. ----------------------------------------------------------------------
  2800. 2.10.    Sybase Network Issues
  2801.    
  2802.    
  2803.    ++++++++++++++++++++++++++++++++++++++++++++++
  2804.    Q1. How can I make Sybase talk to two separate ethernet interfaces on
  2805.       our server?
  2806.    
  2807.    Answer:     You can have as many master entries in the interfaces file for
  2808.    the protocol/port combinations that you have. Simply add a new line for the
  2809.    alternate hostname assigned to the second ethernet port, e.g.
  2810.    
  2811.    The interfaces entry was:
  2812.         SYBASE
  2813.          query tcp sun-ether primename 2025
  2814.          master tcp sun-ether primename 2025
  2815.          console tcp sun-ether primename 2026
  2816.          debug tcp sun-ether primename 2027
  2817.    
  2818.    And it now is
  2819.         SYBASE
  2820.          query tcp sun-ether primename 2025
  2821.          query tcp sun-ether secondname 2025
  2822.          master tcp sun-ether primename 2025
  2823.          master tcp sun-ether secondname 2025
  2824.          console tcp sun-ether primename 2026
  2825.          debug tcp sun-ether primename 2027
  2826.    
  2827.    The key on the server end is the master line not the query line.
  2828.    
  2829.    ++++++++++++++++++++++++++++++++++++++++++++++
  2830.    Q2. Can I use Sybase over PPP (Peer-to-Peer protocol)?
  2831.  
  2832.    Answer:    Yes. The PPP interface to your host is an extra interface with a
  2833.    new hostname. If you look in Sybase's interface file you'll see that you
  2834.    specify a hostname and a portnumber. This means that Sybase will listen to
  2835.    that particular portnumber on the interface that corresponds with the
  2836.    hostname specified in the interfaces file. This is probably your ethernet.
  2837.    Telnet and friends listen to ANYHOST, a special ip-address that translates to
  2838.    any interface that is up in the kernel.
  2839.    The solution is simple and a bit Sybase version specific. First the hacks.
  2840.  
  2841.    1.  ANYHOST is implemented as ip address 0.0.0.0. If you add a host ALL to
  2842.       your hostfile and use ALL as hostname in the interfaces file, Sybase will
  2843.       pass 0.0.0.0 as ip address to the kernel and listens to its portnumber on
  2844.       all interfaces.
  2845.  
  2846.    2. Some versions of Sybase appear to have the constant hostname NULLHOST
  2847.       built in. Principle the same as 1.
  2848.  
  2849.    3. Now the proper solution. I don't know which version you need. Probably at
  2850.       least 4.8. May also be platform specific. But you can add more than one
  2851.       tcp line to the interfaces file (See previous Question). You can
  2852.       duplicate the line for "master" for each interface you want Sybase to
  2853.       listen to (that is duplicate with the appropriate hostname).
  2854.  
  2855.    dave@exlog.com (Dave St.Clair)
  2856.    
  2857. ======================================================================
  2858. 3.       Sybase Core Applications
  2859.  
  2860. ----------------------------------------------------------------------
  2861. 3.1.     Open Client
  2862.    
  2863.    
  2864.    ++++++++++++++++++++++++++++++++++++++++++++++
  2865.    Q1.  Has anyone implemented a C++ class library for Sybase?
  2866.  
  2867.    Answer:    A class library in this context provides a mechanism for allowing
  2868.    an object-oriented language such as C++ to access and manipulate database
  2869.    objects. Some of these class libraries provide an abstraction of multiple
  2870.    databases, such as Oracle, Ingres, and Sybase, to provide a single library of
  2871.    routines to access all of these different products.
  2872.    
  2873.    See the archive ftp.acs.ncsu.edu:/pub/sybase++ for info. Section 9.2 below,
  2874.    also provides sources of commercial products that have implemented database
  2875.    class libraries.
  2876.    
  2877.    
  2878.    ++++++++++++++++++++++++++++++++++++++++++++++
  2879.    Q2.  How can I use the Sybase Open Client with my C++ code?
  2880.  
  2881.    Answer:    Create a header file like the following and you're all set.
  2882.    
  2883.         #ifndef _FIX_SYBASE_H
  2884.         #define _FIX_SYBASE_H
  2885.         
  2886.         #define COMPILE_STYLE CPP_COMPILE
  2887.         
  2888.         extern "C"
  2889.         {
  2890.         #include "sybfront.h"
  2891.         #include "sybdb.h"
  2892.         };
  2893.         
  2894.         #endif /* ifndef _FIX_SYBASE_H */
  2895.    
  2896.    ++++++++++++++++++++++++++++++++++++++++++++++
  2897.    Q3.  Which C compiler(s) is the DOS version of the Open Client software
  2898.       compatible with?
  2899.  
  2900.    Answer:    The Open Client was compiled using Microsoft C.
  2901.  
  2902.    David Benua (dbenua@panix.com) had this to say... I haven't tried this with
  2903.    the Sybase OC, but I've seen this problem with a number of other vendor's SW
  2904.    packages.  Normally the problem is that the .LIB was built to import routines
  2905.    from MLIBCEW.LIB (or some other such library). I've gotten around this by
  2906.    building an empty lib (with the Borland lib program) named MLIBCEW.LIB and
  2907.    including it in the load list.
  2908.    
  2909.    
  2910.  
  2911. ----------------------------------------------------------------------
  2912. 3.2.     Open Server
  2913.    
  2914.  
  2915. ----------------------------------------------------------------------
  2916. 3.3.     APT
  2917.    
  2918.    ++++++++++++++++++++++++++++++++++++++++++++++
  2919.    Q1.  Is it possible to place other visible fields on top of invisible
  2920.       fields, or do I have to have big open spaces?
  2921.  
  2922.    Answer:    There was not, until version 5.0, a way to store necessary lookup
  2923.    data, foreign keys, and other miscellaneous data storages in an address space
  2924.    on the client that many fpo's need access to.  The largest problem with the
  2925.    variables in fpo's is that they are automatic, and are gone as soon as the
  2926.    procedure exits.  Global variables in 5.0 help, but only if you can tolerate
  2927.    only one value for a variable for all forms in a system at all times.  Even
  2928.    under 5.3 APT, there is no way to store a GROUP that your application code
  2929.    needs on the client anywhere but hidden on the form.
  2930.    Any perceived performance hit always involved a very busy client machine (in
  2931.    which all client OS processes were lagging), or involved poor thoughtput on
  2932.    the SQL Server, or the network between the two.  With modern, midrange
  2933.    hardware, APT has never benn, nor should be, a performance bottleneck in and
  2934.    of itself.
  2935.  
  2936.  
  2937. ----------------------------------------------------------------------
  2938. 3.4.     DWB
  2939.    
  2940.  
  2941. ----------------------------------------------------------------------
  2942. 3.5.     Report Writer
  2943.    
  2944.    
  2945.    ++++++++++++++++++++++++++++++++++++++++++++++
  2946.    Q1.  How can I load the reports into a production db in a batched (non-
  2947.       interactive) way?
  2948.  
  2949.    Answer:    Report Writer only wants to load them interactively.  This does
  2950.    not integrate with reasonable procedures of code management and software
  2951.    change control.  Thanks to M. Cushman for this answer.
  2952.    
  2953.  
  2954. ----------------------------------------------------------------------
  2955. 3.6.    Gain Momemtum
  2956.    
  2957. ======================================================================
  2958. 4.  Third Party Applications
  2959.    
  2960.  
  2961. ----------------------------------------------------------------------
  2962. 4.1.     User Interface/Client Applications
  2963.    
  2964.    ++++++++++++++++++++++++++++++++++++++++++++++
  2965.    1.  JYACC JAM/DBi
  2966.    Company:  JYACC, Inc.
  2967.    Address:  116 John Street
  2968.              -or- One Sansome St., Suite 2100
  2969.              New York, NY 10038 San Francisco, CA 94104
  2970.    Phone:  800-458-3313 415-951-1070
  2971.    Fax:
  2972.    Summary:
  2973.    
  2974.    
  2975.    ++++++++++++++++++++++++++++++++++++++++++++++
  2976.    2.  Uniface
  2977.    Company:
  2978.    Address:
  2979.    Phone:  410-740-8745 -or- 510-748-6145
  2980.    Fax:
  2981.    Summary:
  2982.    
  2983.    
  2984.    ++++++++++++++++++++++++++++++++++++++++++++++
  2985.    3.  Power Builder (Microsoft Windows only)
  2986.    Company:  Powersoft Corporation
  2987.    Address:  70 Blanchard Road
  2988.              Burlington, MA 01803
  2989.    Phone:  617-229-2200
  2990.    Fax:
  2991.    Summary:
  2992.    
  2993.    
  2994.    ++++++++++++++++++++++++++++++++++++++++++++++
  2995.    4.  Microsoft Access/Visual Basic
  2996.    Company:  Microsoft Corp.
  2997.    Address:
  2998.    Phone:
  2999.    Fax:
  3000.    Summary:
  3001.    Windows 3.1
  3002.    
  3003.    
  3004.    ++++++++++++++++++++++++++++++++++++++++++++++
  3005.    5.  DataEase
  3006.    Company:  DataEase International, Inc.
  3007.    Address:  7 Cambridge Drive
  3008.              Trumbull, CT  06611
  3009.    Phone:  (203) 374-8000
  3010.    Fax:
  3011.    Summary:
  3012.    
  3013.    
  3014.    ++++++++++++++++++++++++++++++++++++++++++++++
  3015.    6.  Unify
  3016.    Company:
  3017.    Address:  3901 Lennane Drive
  3018.              Sacramento, CA 95834-1922
  3019.    Phone:  800-24-UNIFY
  3020.    Fax:
  3021.    Summary:
  3022.    
  3023.    
  3024.    ++++++++++++++++++++++++++++++++++++++++++++++
  3025.    7.  Focus
  3026.    Company:  Information Builders, Inc.
  3027.    Address:  1250 Broadway
  3028.              New York, NY
  3029.    Phone:  212-736-4433
  3030.    Fax:
  3031.    Summary:
  3032.    
  3033.    
  3034.    ++++++++++++++++++++++++++++++++++++++++++++++
  3035.    8.  ObjectView
  3036.    Company:  KnowlegeWare Inc
  3037.    Address:  3340 Peachtree Road, N.E.
  3038.              Suite 1100
  3039.              Atlanta, GA 20226
  3040.    Phone:  (404) 231-8575
  3041.    Fax:
  3042.    Summary:
  3043.    Windows 3.1
  3044.    Supports DDE
  3045.    Workgroup edition available
  3046.    
  3047.    
  3048.    ++++++++++++++++++++++++++++++++++++++++++++++
  3049.    9.  Q+E
  3050.    Company:  Pioneer Software
  3051.    Address:
  3052.    Phone:
  3053.    Fax:
  3054.    Summary:
  3055.    Windows 3.1.
  3056.    Simple spreadsheet-like browser.
  3057.    Can be used as an OLE object.
  3058.    
  3059.    
  3060.    ++++++++++++++++++++++++++++++++++++++++++++++
  3061.    10. Superbase
  3062.    Company:  SPC Software
  3063.    Address:
  3064.    Phone:
  3065.    Fax:
  3066.    Summary:
  3067.    Windows 3.1
  3068.    Complete database forms/report/application package.
  3069.    SQL link purchased separately.
  3070.    Can be used as an OLE object.
  3071.    
  3072.    
  3073.    ++++++++++++++++++++++++++++++++++++++++++++++
  3074.    11. R&R Report Writer for Windows, SQL Edition
  3075.    Company:
  3076.    Address:
  3077.    Phone: 508-366-1122
  3078.    Fax:
  3079.    Summary:
  3080.    Windows 3.?
  3081.    Supports Sybase SQL Server, Microsoft SQL Server,
  3082.    Oracle, Netware SQL, Btrieve, and dBASE databases
  3083.    
  3084.    
  3085.    ++++++++++++++++++++++++++++++++++++++++++++++
  3086.    12. CorVu
  3087.    Company:Sycomp Pty Ltd
  3088.    Address:  Level 4
  3089.            16.  James Place
  3090.            North Sydney 2060
  3091.            AUSTRALIA
  3092.    Phone:  +61 2 959 3522
  3093.    Fax:    +61 2 959 3583
  3094.    Summary: CorVu is an end user graphical query and report writing tool with
  3095.    decision support and forecasting options. Requires Microsoft Windows 3.1. Can
  3096.    use ODBC or Sycomp's own communications layer, which is faster than and
  3097.    avoids the need to have Sybase's Open DB-library on each client machine.
  3098.    
  3099.  
  3100. ----------------------------------------------------------------------
  3101. 4.2.     Class Libraries
  3102.    
  3103.    ++++++++++++++++++++++++++++++++++++++++++++++
  3104.    1.   DBh++
  3105.    Rogue Wave
  3106.    
  3107.    
  3108.    ++++++++++++++++++++++++++++++++++++++++++++++
  3109.    2.  C++ API
  3110.    Qualix email at info@qualix.com
  3111.    
  3112.    
  3113.    ++++++++++++++++++++++++++++++++++++++++++++++
  3114.    3.  Persistence
  3115.    Persistence Software
  3116.    
  3117.  
  3118. ----------------------------------------------------------------------
  3119. 4.3.     Other Miscellaneous Products and Tools
  3120.    
  3121.    ++++++++++++++++++++++++++++++++++++++++++++++
  3122.    1.   SybPERL
  3123.    
  3124.    
  3125.    ++++++++++++++++++++++++++++++++++++++++++++++
  3126.    2.  SQL-BackTrack
  3127.    Company:  DataTools, Inc.
  3128.    Address:
  3129.    Phone:
  3130.    Fax:
  3131.    Summary:  A complete backup and recovery tool for Sybase. Its
  3132.    features include:
  3133.       object-level backup and recovery,
  3134.       automated and remote backups
  3135.       backups to ANSI-labeled tape, disk, optical disk, and Legato NetWorker.
  3136.       logical and physical format backups (logical format backups are device-
  3137.       ,OS-and Sybase version-independent, which means you can move data from
  3138.       4.1 to 4.9 or 10.
  3139.       incremental backups
  3140.       data compression and data encryption
  3141.    
  3142.    Also, for the record, SQL-BackTrack writes multiple dumps to a single tape
  3143.    (3.4-1), as well as dumps spanning tapes.
  3144.    
  3145.    DataTools has a marketing agreement with Sybase to support System 10, and has
  3146.    a paper comparing the SQL-BackTrack backup facilities with System 10 and
  3147.    describing how SQL-BackTrack will extend the System 10 Backup Server.
  3148.    
  3149.    Documentation and literature available upon request.
  3150.    
  3151.    
  3152.    ++++++++++++++++++++++++++++++++++++++++++++++
  3153.    3.  dbViewer
  3154.    Qualix
  3155.    
  3156.    
  3157.    ++++++++++++++++++++++++++++++++++++++++++++++
  3158.    4.  Xsybmon
  3159.    Shareware by David Joyner
  3160.    Comments:  Xsybmon wraps up all the statistics covered by sp_monitor as well
  3161.    as some other useful information in a Motif interface.  The latest version is
  3162.    available via anonymous FTP from:
  3163.    
  3164.    straylight.acs.ncsu.edu:/pub/sybase
  3165.    
  3166.    
  3167.    ++++++++++++++++++++++++++++++++++++++++++++++
  3168.    5.  Sybtcl
  3169.    Comments:  Sybtcl is an extension to Tool Command Language (Tcl) that
  3170.    provides access to a Sybase Database server.  Sybtcl adds additional Tcl
  3171.    commands that login to a SQL Server, pass SQL code, read results, etc.
  3172.    Sybtcl was inspired by similar tools written for Perl (sybperl, oraperl) but
  3173.    was written from scratch instead of borrowing on the work of either Perl
  3174.    extension.
  3175.    
  3176.    Sybtcl features:
  3177.    
  3178.    o    supports multiple connections to the same or different SQL Servers
  3179.    o    provides "nextrow" processing for regular and compute return rows
  3180.    o    converts results to strings and returns rows as Tcl lists
  3181.    o    allows user defined null values to be returned
  3182.    o    stored procedures can be executed and return values accessed
  3183.    o    accesses column names, lengths, and datatypes of rows & return values
  3184.    o    provides feedback of SQL Server and DB-Lib messages
  3185.    o    reads/writes text or image datatypes to files
  3186.    
  3187.    Sybtcl does not:
  3188.    
  3189.    o    perform row buffering or browse mode
  3190.    o    bulk copies
  3191.    o    support two phase commit on multiple servers
  3192.    
  3193.    REQUIREMENTS
  3194.    
  3195.    Since Sybtcl is an extension to Tcl, you should already have Tcl, or be
  3196.    prepared to get it via Ftp [sites listed below].
  3197.    
  3198.    Of course, you must also have access to a Sybase Databaser Server.
  3199.    Additionally, you must have the Sybase Open Client (aka "DB-Library") package
  3200.    that provides header files and object libraries;  Sybtcl must be linked with
  3201.    libsybdb.a.
  3202.    
  3203.    I normally build Sybtcl with Tcl, Extended Tcl, and the X11 Tk widget set
  3204.    yielding tcl and wishx interpreters.  Sybtcl is written with no dependencies
  3205.    other than Tcl, so it should be possible to link it with the the minimal Tcl
  3206.    library.  (Although Sybtcl uses "handles", I didn't rely on the handle
  3207.    functions provided by Extended Tcl.)
  3208.    
  3209.    The distribution sybtcl-1.3.tar.Z is on harbor.ecn.purdue.edu in
  3210.    /pub/tcl/extensions.
  3211.    
  3212.    Tom Poindexter, tpoind@advtech.uswest.com  or tpoindex@nyx.cs.du.edu
  3213. -- 
  3214. +==============================+=============================================+
  3215. | David W. Pledger             | S T R A T E G I C   D A T A   S Y S T E M S |
  3216. | davidp@meaddata.com          |           PO Box 498, Springboro, OH  45066 |
  3217. | Custom Database Applications | Phone (513)748-2460, (800)253-5624 ext 2940 |
  3218. --
  3219. +==============================+=============================================+
  3220. | David W. Pledger             | S T R A T E G I C   D A T A   S Y S T E M S |
  3221. | davidp@meaddata.com          |           PO Box 498, Springboro, OH  45066 |
  3222. | Custom Database Applications | Phone (513)748-2460, (800)253-5624 ext 2940 |
  3223.